2

我正在使用以下代码,在某些神秘的情况下,添加的结果与预期的不同:

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 是造成这种“错误计算”的原因,但我需要弄清楚是哪一个。谁能给我一个提示如何找出我的问题的根源?

4

5 回答 5

10

double 不完全准确,请尝试使用 decimal

使用 double 和 float 而不是小数的优点是性能

于 2009-07-28T12:01:00.147 回答
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.SingleandSystem.Double类型相关的舍入错误的情况下使用。

然而,话虽如此,这里的情况并非如此。通过在给定点任意舍入数字,您假设该类型也将在同一点舍入,这不是它的工作方式。浮点数存储到它们的最大表示容量,并且只有在达到该阈值时才会进行舍入。

于 2009-07-28T12:01:05.763 回答
1

问题是 Double 的精度只有 15 - 16 位(在你的例子中你似乎需要更高的精度),而 Decimal 的精度是 28 - 29。你是如何在 Double 和 Decimal 之间转换的?

于 2009-07-28T12:09:59.677 回答
0

你被四舍五入和精度问题所困扰。看到这个。十进制可能会有所帮助。转到此处了解有关转换和舍入的详细信息。

来自 MSDN:

将 float 或 double 转换为十进制时,源值将转换为十进制表示形式,并根据需要四舍五入到小数点后 28 位后最接近的数字。根据源值的值,可能会出现以下结果之一:

如果源值太小而无法表示为小数,则结果为零。

如果源值是 NaN(不是数字)、无穷大或太大而无法表示为小数,则会引发 OverflowException。

于 2009-07-28T12:06:01.353 回答
0

您不能用二进制系统中的浮点数准确地表示十进制系统中的每个浮点数,这甚至与十进制数的“小”程度没有直接关系,有些数字只是不“适合”基数- 2不错。

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

Decimal要以(128 位浮点)精度指定常量,请使用以下声明:

decimal _west = 9.482935905456543m;
decimal _off = 0.00000093248155508263153m;
decimal _lon = _west + _off;
于 2009-07-28T12:10:34.463 回答