添加两个双误给出结果(add two double given wrong result)

2019-09-21 04:26发布

我使用下面的代码段,并在一些神秘的情况下,加入的结果并不像它应该是:

double _west = 9.482935905456543;
double _off = 0.00000093248155508263153;
double _lon = _west + _off;

// check for the expected result
Debug.Assert(_lon == 9.4829368379380981);
// sometimes i get 9.48293685913086 for _lon (which is wrong)

我用我的应用程序中的一些原生的DLL,我怀疑某些DLL是负责这个“失算”,但我需要找出哪一个。 谁能给我一个提示,如何找出我的问题的根源在哪里?

Answer 1:

双不完全准确,请尝试使用小数代替

采用双并浮到小数点advanteage是性能



Answer 2:

起初我以为这是一个舍入误差,但实际上它是你的断言是错误的。 试着增加你的计算的全部结果,而不需要您任意四舍五入。

尝试这个:

using System;

class Program
{
    static void Main()
    {
        double _west = 9.482935905456543;
        double _off = 0.00000093248155508263153;
        double _lon = _west + _off;

        // check for the expected result
        Console.WriteLine(_lon == 9.48293683793809808263153);       
    }
}

在未来,虽然最好是使用System.Decimal在你需要避免通常与相关的舍入误差的情况下System.SingleSystem.Double类型。

话虽这么说,但是,这是不是这里的情况。 通过在一个给定的点任意舍入数假定你是该类型也将一轮相同点,这是不是它是如何工作的。 浮点数字存储到他们的最大代表能力,只有一旦已经达到阈值并四舍五入取的地方。



Answer 3:

您正在被舍入和精度问题咬伤。 请参见本 。 小数可能的帮助。 走在这里的上转换和四舍五入的细节。

从MSDN:

当转换浮点或双精度到十进制,源值转换为十进制表示,并且如果需要的28位小数后四舍五入到最接近的数字。 取决于源值的值,可能会发生以下结果之一:

如果源值太小而不能表示为小数,结果变为零。

如果源值为NaN(非数字),无穷大,或过大而不能表示为小数,一个发生OverflowException异常。



Answer 4:

问题是,双只有15精度 - 16位(好像你需要在你的例子更精确),而小数有精确到28 - 29。你是如何双人床和十进制之间的转换?



Answer 5:

你不能代表在精确的二进制系统浮点十进制系统中的每个浮点数,这甚至是没有直接关系的“小”的十进制数是怎么了,有些数字只是不“适合”的碱基2好听。

使用较长的位宽在大多数情况下有所帮助,但并非总是如此。

要在指定的常量Decimal (128位浮点)精度,使用此声明:

decimal _west = 9.482935905456543m;
decimal _off = 0.00000093248155508263153m;
decimal _lon = _west + _off;


文章来源: add two double given wrong result