float表示的数并不连续的原因

昨天室友跟我提到了一个特别奇怪的情况

float f=0;
for(int i=0;i<1e8;++i)++f;
printf("%f",f);

然后结果非常尴尬,本该输出 10 8 ,然而结果却是 2 24 :16777216,原因?
浮点数标准IEE754里浮点数前一位为符号位,再八位为指数位,最后23位为小数位。
当浮点数f为16777216时,表示为 2 24 ( 1 + 0 ) .
二进制表示为:

0 0 0011000 0 00000000000000000

我们这时能增加的最小的值就是将23位小数位的最后一位变成1
即:
0 0 0011000 0 00000000000000001

最后表示结果为
2 24 ( 1 + 2 23 )

比之前大2,为16777218.

也就是说16777217这个数没有办法用一个单精度浮点数表示,
也就是说之前的程序把f加到16777216之后再对f+1成为的16777217不能被表示,于是就又自动缩回16777216,也就导致了不论怎么++也不变的尴尬情况。

这也再一方面说明了实际上浮点数并不是连续的,而是离散的。这与我们正常人的感觉相悖。
实际上可以推导单精度浮点数在8388608之后就不能表示小数,在16777216之后就不能表示奇数,在 33554432之后每两个能表示的数之间的间隔就是4。

本文原创,没有作者本人同意禁止转载.

猜你喜欢

转载自blog.csdn.net/qq_21201963/article/details/80174833
今日推荐