.NET浮点型向双精度型的转换

5

有人能解释一下为什么下面的第三个输出打印出的值比预期值少128吗?

我在目标框架为.NET Framework 4的情况下运行了以下代码:

代码:

    static void Main(string[] args)
    {
        float f = 3510000000f;
        double d = 3510000000d;

        Console.WriteLine("f = {0:f1}", f);
        Console.WriteLine("d = {0:f1}", d);
        Console.WriteLine("f converted to a double = {0:f1}",
            Convert.ToDouble(f));
        Console.WriteLine("f converted to a double using strings = {0:f1}",
            Convert.ToDouble(f.ToString()));
    }
3个回答

5

3510000000f 的二进制表示为 1101 0001 0011 0110 0101 1001 1000 0000。你有一个具有25位精度的数字,而.Net浮点数只有24位精度。因此,在转换为double时,你失去了精度。在这种情况下,它向上舍入为 1101 0001 0011 0110 0101 1010 0000 0000


+1 这个例子比我给出的要清晰得多,尽管与 IEEE 754 表示的关系一开始并不明显。 - Zooba

3
基本上,这是一个取整误差。
在浮点数值的二进制表示中,指数和尾数是分开的。这意味着在内部,您的数字表示为:
(1.634471118450164794921875) * 2^31

然而,该数字的第一部分仅限于23位(32位浮点数的维基百科),因此我们必须四舍五入到最近的2^-23

(1.634471118450164794921875) % (0.00000011920928955078125) = 
 1.6344711780548095703125

所以你的号码实际上是:

(1.6344711780548095703125) * 2^31

如果我们进行评估,得到的结果是3510000128而不是3510000000
简而言之,当您指定0.1时,会出现相同的舍入误差:由于表示的限制,两者都无法准确表达。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接