昨天室友跟我提到了一个特别奇怪的情况
float f=0;
for(int i=0;i<1e8;++i)++f;
printf("%f",f);
然后结果非常尴尬,本该输出
,然而结果却是
:16777216,原因?
浮点数标准IEE754里浮点数前一位为符号位,再八位为指数位,最后23位为小数位。
当浮点数f为16777216时,表示为
.
二进制表示为:
我们这时能增加的最小的值就是将23位小数位的最后一位变成1
即:
最后表示结果为
比之前大2,为16777218.
也就是说16777217这个数没有办法用一个单精度浮点数表示,
也就是说之前的程序把f加到16777216之后再对f+1成为的16777217不能被表示,于是就又自动缩回16777216,也就导致了不论怎么++也不变的尴尬情况。
这也再一方面说明了实际上浮点数并不是连续的,而是离散的。这与我们正常人的感觉相悖。
实际上可以推导单精度浮点数在8388608之后就不能表示小数,在16777216之后就不能表示奇数,在 33554432之后每两个能表示的数之间的间隔就是4。
本文原创,没有作者本人同意禁止转载.