.Net浮动到双重转换

use*_*895 4 .net

任何人都可以解释为什么下面的第三个输出打印出一个从预期值128的值?

我使用Target framework = .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()));
    }
Run Code Online (Sandbox Code Playgroud)

Joe*_*eau 5

3510000000f用比特表示1101 0001 0011 0110 0101 1001 1000 0000.你有一个25位精度的数字,而.Net浮点数只有24位精度.因此,当转换为double时,您的精度会下降.在这种情况下,它向上舍入到1101 0001 0011 0110 0101 1010 0000 0000.


Zoo*_*oba 3

基本上,这是一个舍入误差。

在浮点值的二进制表示中,指数尾数是分开的。这意味着在内部,您的号码表示为:

(1.634471118450164794921875) * 2^31
Run Code Online (Sandbox Code Playgroud)

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

(1.634471118450164794921875) % (0.00000011920928955078125) = 
 1.6344711780548095703125
Run Code Online (Sandbox Code Playgroud)

所以你的号码实际上是:

(1.6344711780548095703125) * 2^31
Run Code Online (Sandbox Code Playgroud)

如果我们评估这一点,我们会得到3510000128而不是3510000000

简而言之,这与指定 时得到的舍入误差相同0.1:鉴于表示形式的限制,两者都无法准确表达。