【发布时间】:2015-02-02 15:47:01
【问题描述】:
我是来求知的。
我正在尝试理解浮点数。
我试图弄清楚为什么当我打印最大的浮点数时,它不能正确打印。
2-(2^-23) Exponent Bits
1.99999988079071044921875 * (1.7014118346046923173168730371588e+38) =
3.4028234663852885981170418348451e+38
这应该是最大的单精度浮点数:
340282346638528859811704183484510000000.0
所以,
float i = 340282346638528859811704183484510000000.0;
printf(TEXT, "Float %.38f", i);
Output: 340282346638528860000000000000000000000.0
显然这个数字正在四舍五入,所以我想弄清楚到底发生了什么。
我的问题是:
Wikipedia 文档指出,3.4028234663852885981170418348451e+38 是 IEEE-754 定点可以表示的最大数字。
浮点寄存器中存储的数字是否=0 11111111 11111111111111111111111,只是显示不正确?
如果我写printf(TEXT, "Float %.38f", FLT_MAX);,我会得到相同的答案。
也许我正在使用的计算机不使用 IEEE-754?
我了解计算错误,但我不明白为什么数字
340282346638528860000000000000000000000.0 是可以准确表示的最大浮点数。
也许尾数 * 指数导致计算错误?如果这是真的,那么340282346638528860000000000000000000000.0 将是可以忠实表示而不会出现计算错误的最大数字。我想这是有道理的。只需要祝福。
谢谢,
【问题讨论】:
-
“0 11111111 11111111111111111111111”是 NAN。怀疑你想要“0 11111110 11111111111111111111111”
-
FLT_MAX就是你想的那样。您的printf()显示了它的近似值。要查看确切是FLT_MAX的十进制值,您需要使用不同的代码。 -
维基百科还说“这给出了 6 到 9 位有效十进制数字的精度”,因此在日常使用中作为某个附近值的近似值,试图打印所有数字,就好像它是一个特定的整数一样量级有点傻。之前的 10^~30 个整数都不可表示。有趣的是 printf 显示了通常在双精度值中有意义的位数 - 我的猜测是您的实现将浮点数转换为双精度,生成一个合理的表示,并用 0 填充到请求的长度.
-
@Tony D
printf(TEXT, "Float %.38f", i);将i从float转换为double,然后将其传递给printf()。printf()没有收到float。 -
@chux: 是的,当然......所以显示比这更低的精度是不合理的......而且显然实现显示更多是毫无意义的。