2
public static void Main()
{
    Dictionary<string, double> values = new Dictionary<string, double>();
    values.Add("a", 0.002);
    values.Add("b", 0.003);
    values.Add("c", 0.012);

    // Summing iteratively.
    double v1 = 615.0;
    foreach (KeyValuePair<string, double> kp in values)
    {
        v1 += kp.Value;
    }

    Console.WriteLine(v1);

    // Summing using the Sum method.
    double v2 = 615.0;
    v2 += values.Values.Sum();

    Console.WriteLine(v2);

    Console.ReadLine();
}

当我在调试器中查看 v1 的值时,它给出的值为 615.01699999999994,但对于 v2,它给出的值为 615.017。由于某种原因,Sum 方法会产生准确的结果,而对它们进行迭代求和则不会。(当我打印这两个值时,它们是相同的,但我认为这是由于 WriteLine 方法所做的一些舍入。)

有人知道这里发生了什么吗?

4

2 回答 2

6

浮点数学本质上不是 100% 准确并且有错误。将不同数字相加的顺序会影响浮点误差的大小。如果这些计算完全准确很重要,您应该使用十进制,而不是双精度。

这与使用 Sum 与手动对数据求和没有任何关系。在第一个中,您将每个数字添加到 615,在第二个中,您将所有数字相互添加,然后将它们添加到 615。这是添加相同数据的不同顺序。根据您使用的数字,任何一种方法都可能导致或多或少的错误。

于 2012-04-07T16:38:32.390 回答
0

double/float 的问题在于它们是二进制数,内部也称为 1000110.10101001,因此仅代表您的值的近似表示。

阅读 Jon Skeet 的解释:.NET 中十进制、浮点和双精度的区别?

于 2012-04-07T16:51:30.143 回答