打印最大的单精度浮点数

时间:2014-12-04 16:52:20

标签: c++ c printf ieee-754

我来寻求知识 我想了解浮点数。
我试图弄清楚为什么,当我打印最大的浮点数时,它无法正确打印。

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

显然这个数字正在四舍五入,所以我试图找出究竟发生了什么。

我的问题是: 维基百科文档指出3.4028234663852885981170418348451e+38是可以在IEEE-754定点中表示的最大数字。

浮点寄存器中存储的数字是否为0 11111111 11111111111111111111111,而且显示不正确?

如果我写printf(TEXT, "Float %.38f", FLT_MAX);,我会得到相同的答案。 也许我使用的计算机不使用IEEE-754?

我理解计算错误,但我不明白为什么这个数字 340282346638528860000000000000000000000.0是可以准确表示的最大浮点数。

可能Mantissa * Exponent导致计算错误?如果这是真的,那么340282346638528860000000000000000000000.0将是可以忠实地表示而没有计算错误的最大数字。我想那是有道理的。只需要一个祝福。

谢谢,

2 个答案:

答案 0 :(得分:4)

看起来罪魁祸首是printf()(我猜是因为float在传递给double时被隐式转换为#include <iostream> #include <limits> int main() { std::cout.precision( 38 ); std::cout << std::numeric_limits<float>::max() << std::endl; }

3.4028234663852885981170418348451692544e+38

输出是:

{{1}}

答案 1 :(得分:3)

floatbinary32,最大有限float

  

340282346638528859811704183484516925440.0

printf("%.1f", FLT_MAX)没有义务精确打印到38位以上的有效数字,因此看到如下所示的输出并非出乎意料。

  

340282346638528860000000000000000000000.0

printf()会将浮点精确打印到DECIMAL_DIG个有效数字。 DECIMAL_DIG位于至少 10。如果指示的DECIMAL_DIG重要性超过printf(),则符合{{1}}可能会在某个时间点对结果进行舍入。 C11dr§7.21.6.16详细介绍。