C#中的15位数的Double Type精度是不是?

时间:2009-09-08 18:54:19

标签: c# types precision

我正在从Brainteasers:

测试此代码
        double d1 = 1.000001;

        double d2 = 0.000001;

        Console.WriteLine((d1 - d2) == 1.0);

结果是“假”。当我更改数据类型时:

        decimal d1 = 1.000001M;

        decimal d2 = 0.000001M;

        decimal d3 = d1-d2;

        Console.WriteLine(d3 == 1);

程序写出正确的答案:“True”。

此问题仅在浮点后使用6位数。 15位数的精度怎么样?

6 个答案:

答案 0 :(得分:28)

这与精度无关 - 它与表示性舍入误差有关。

System.Decimal能够表示大浮点数,并且可以显着降低发生任何舍入错误的风险,例如您所看到的错误。 System.SingleSystem.Double无法解决此问题,并会将这些数字四舍五入,并产生类似于您在示例中看到的问题。

System.Decimal使用缩放因子来保存小数位的位置,从而允许精确表示给定的浮点数,而System.SingleSystem.Double仅接近您的值最好的。

有关详细信息,请参阅System.Double

  

记住一个浮点数   只能近似一个十进制数,   并且精确度   浮点数决定了如何   准确地说,这个数字近似于a   十进制数。默认情况下,为Double   value包含15位十进制数字   精度,虽然最多17   数字在内部维护。该   浮点数的精度   有几个后果:

     
      
  • 两个浮点数对于特定的看似相等   精度可能无法相等   因为他们的最低有效数字   是不同的。

  •   
  • 使用浮点数的数学或比较运算   数字可能不会产生相同的结果   如果使用十进制数,因为   浮点数可能不会   完全接近小数   号。

  •   

答案 1 :(得分:8)

通常,检查浮点值是否相等的方法是检查 near -equality,即检查接近最小值的差值(称为 epsilon) )用于该数据类型。例如,

if (Math.Abs(d1 - d2) <= Double.Epsilon) ...

此测试用于查看d1d2是否由相同的位模式表示给出或取最低有效位。

更正 (2015年3月2日新增)

经过进一步检查,代码应该更像这样:

// Assumes that d1 and d2 are not both zero
if (Math.Abs(d1 - d2) / Math.Max(Math.Abs(d1), Math.Abs(d2)) <= Double.Epsilon) ...

换句话说,取d1d2之间的绝对差值,然后按d1d2的最大值进行缩放,然后 em>将其与Epsilon进行比较。

<强>参考
http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx
http://msdn.microsoft.com/en-us/library/system.double.aspx#Precision

答案 2 :(得分:6)

十进制类型实现十进制浮点,而 double 是二进制浮点。

十进制的优点在于它在舍入方面表现得像人类一样,如果用十进制值初始化它,那么该值按照您的指定存储精确。这仅适用于有限长度的十进制数,并且在可表示的范围和精度内。如果你用1.0M / 3.0M初始化它,那么就不会像在纸上写0.33333一样精确地存储它。

如果初始化带有小数的二进制FP值,它将从人类可读的十进制形式转换为很少完全相同的二进制表示。

十进制类型的主要目的是实现财务应用程序,在.NET实现中它的精度也比double高得多,但二进制FP直接由硬件支持,因此显着比十进制FP操作快。

请注意,double精确到大约15 有效数字而不是15 小数位 d1 初始化为7有效数字值而非6,而 d2 仅有1位有效数字。它们具有显着不同的幅度这一事实也无济于事。

答案 3 :(得分:3)

浮点数字的概念是它们对于特定数字的数字并不精确。如果您需要这种功能,则应查看decimal数据类型。

答案 4 :(得分:3)

精度不是绝对的,因为不可能精确地在十进制和二进制数之间进行转换。

在这种情况下,当以二进制表示时,.1十进制将永远重复。它转换为.000110011001100110011 ...并永远重复。没有多少精确度可以准确存储。

答案 5 :(得分:2)

避免比较浮点数的相等性。