我来寻求知识
我想了解浮点数。
我试图弄清楚为什么,当我打印最大的浮点数时,它无法正确打印。
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
将是可以忠实地表示而没有计算错误的最大数字。我想那是有道理的。只需要一个祝福。
谢谢,
答案 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)
float
为binary32,最大有限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详细介绍。