-3
double c, d, e;
double a = (c - d) / e;
double b = Math.Floor(a);
Debug.WriteLine(a.ToString() + " " + b.ToString());

上面的代码在所有数字都是双倍的一种配置下输出“3 2”。这怎么可能?是因为双重操作导致的小数误差吗?但是我认为a.ToString()应该给出整数及其小数部分。

4

1 回答 1

10

这只是做什么的double.ToString()问题。这是一个简短但完整的程序,演示了同样的事情:

using System;

public class Test
{
    static void Main(string[] args)
    {
        // Find the largest double less than 3
        long bits = BitConverter.DoubleToInt64Bits(3);
        double a = BitConverter.Int64BitsToDouble(bits - 1);
        double b = Math.Floor(a);
        // Print them using the default conversion to string...
        Console.WriteLine(a.ToString() + " " + b.ToString());
        // Now use round-trip formatting...
        Console.WriteLine(a.ToString("r") + " " + b.ToString("r"));
    }
}

输出:

3 2
2.9999999999999996 2

现在double.ToString()记录在案:

此版本的 ToString 方法隐式使用通用数字格式说明符 ("G") 和当前区域性的 NumberFormatInfo。

...和通用数字格式说明符文档状态:

精度说明符定义可以出现在结果字符串中的有效数字的最大数量。如果精度说明符被省略或为零,则数字的类型确定默认精度,如下表所示。

...其中表格显示默认精度为double15。如果您考虑将 2.9999999999999996 四舍五入为 15 位有效数字,则最终为 3。

实际上,这里的确切a是:

2.999999999999999555910790149937383830547332763671875

...同样,当考虑 15 个有效数字时,它是 3。

于 2013-01-30T21:32:15.850 回答