任何人都可以解释为什么下面的第三个输出打印出一个距预期值128的值吗?
我使用Target framework = .NET Framework 4
运行以下代码CODE:
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()));
}
答案 0 :(得分:5)
3510000000f
为1101 0001 0011 0110 0101 1001 1000 0000
。你有一个25位精度的数字,而.Net浮点数只有24位精度。因此,当转换为double时,您的精度会下降。在这种情况下,它会向上舍入为1101 0001 0011 0110 0101 1010 0000 0000
。
答案 1 :(得分:3)
基本上,这是一个舍入错误。
在浮点值的二进制表示中,指数和尾数是分开的。这意味着在内部,您的号码表示为:
(1.634471118450164794921875) * 2^31
但是,该数字的第一部分仅限于23位(Wikipedia on 32-bit floats),因此我们必须舍入到最近的2^-23
:
(1.634471118450164794921875) % (0.00000011920928955078125) =
1.6344711780548095703125
所以你的号码实际上是:
(1.6344711780548095703125) * 2^31
如果我们对此进行评估,则会得到3510000128
而不是3510000000
。
简而言之,这与您指定0.1
时得到的舍入错误相同:由于表示的限制,两者都无法准确表达。
答案 2 :(得分:0)
引用Jon Skeet:
这不是你真正得到的 额外的精确度 - 这就是浮动 没有准确地代表这个数字 你是最初的目标。该 double表示原始 漂浮; toString正在显示 已经存在的“额外”数据 本。