谁能给我解释一下这是怎么回事:

using System;
using System.Text;

namespace ConsoleApplication1 {

    class Program {

        static void Main(string[] args) {

            object o = 1000000.123f;
            float f= Convert.ToSingle(o);
            double d = Convert.ToDouble(f);

            Console.WriteLine(f.ToString("r"));
            Console.WriteLine(d.ToString("r"));

            Console.ReadLine();

        }
    }
}

哪个输出:

1000000.13

1000000.125

我期望:

对象o具有底层浮点类型([发生在[观察观察窗口将其键入为对象{float}的情况下)

那个1000000.123f将会以1000000.125的形式存储在f中(32位的IEEE754近似值?)

该double也会存储1000000.125(即使f似乎不包含我的预期值,似乎也会发生)

在两种情况下,要求在ToString上使用往返格式将给我1000000.125。

谁能告诉我我在做错什么才能在排除f时得到1000000.13?

最佳答案

如您所见,数字1000000.123被存储为1000000.125。这是通过double.ToString()照原样呈现的,但是被float.ToString()截断了,因为显示太多的数字会产生误导。

顺便说一句,没有Convert.ToSingle(float),因为它只会返回您传入的内容。您的代码实际上是解析为Convert.ToSingle(double)。因此,您(隐式)转换为double,然后(明确)转换回float,从本质上讲,这是一个无操作操作。

警告:不要相信JavaScript浮点计算器。他们中的一些人断言1000000.123由单精度浮点数存储为1000000.1,我猜这是基于这样一个假设,因为IEEE浮点数的精度大约为7.22位,因此它们可以精确地用8位数字表示。这是不正确的。

10-07 14:28