我使用下面的代码段,并在一些神秘的情况下,加入的结果并不像它应该是:
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是负责这个“失算”,但我需要找出哪一个。 谁能给我一个提示,如何找出我的问题的根源在哪里?
起初我以为这是一个舍入误差,但实际上它是你的断言是错误的。 试着增加你的计算的全部结果,而不需要您任意四舍五入。
尝试这个:
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.Single
和System.Double
类型。
话虽这么说,但是,这是不是这里的情况。 通过在一个给定的点任意舍入数假定你是该类型也将一轮相同点,这是不是它是如何工作的。 浮点数字存储到他们的最大代表能力,只有一旦已经达到阈值并四舍五入取的地方。
您正在被舍入和精度问题咬伤。 请参见本 。 小数可能的帮助。 走在这里的上转换和四舍五入的细节。
从MSDN:
当转换浮点或双精度到十进制,源值转换为十进制表示,并且如果需要的28位小数后四舍五入到最接近的数字。 取决于源值的值,可能会发生以下结果之一:
如果源值太小而不能表示为小数,结果变为零。
如果源值为NaN(非数字),无穷大,或过大而不能表示为小数,一个发生OverflowException异常。
问题是,双只有15精度 - 16位(好像你需要在你的例子更精确),而小数有精确到28 - 29。你是如何双人床和十进制之间的转换?
你不能代表在精确的二进制系统浮点十进制系统中的每个浮点数,这甚至是没有直接关系的“小”的十进制数是怎么了,有些数字只是不“适合”的碱基2好听。
使用较长的位宽在大多数情况下有所帮助,但并非总是如此。
要在指定的常量Decimal
(128位浮点)精度,使用此声明:
decimal _west = 9.482935905456543m;
decimal _off = 0.00000093248155508263153m;
decimal _lon = _west + _off;