下面内容是在果壳网上看到的:
这段程序是死循环
float f;
f=1;
while (f < 100000000) {
f = f + 1;
}
而这段不是
int a;
a=1;
while (a>=0) {
a = a + 1;
}
第二个很好理解,int,加到最大就变负数了。
第一个没理解,验证一下是真的。
第一个在循环里加上判断:
if(f== f+1)break;
可以得到f在16777216.000000时不再增加,这是为什么呢?
这是因为浮点数精度是有限的,float的尾数精度是23位,还有一位最高位默认1,总精度是24位,2^24 = 16777216.
16777215:'0b111111111111111111111111'
16777216:'0b1000000000000000000000000'
16777217:'0b1000000000000000000000001'
16777218:'0b1000000000000000000000010'
除了第一位的1以外,16777215有23个1,还在尾数精度内,到16777216已经有24个0了,因为尾数表示是1.0000x2^24,最后的0丢弃也不影响精度。
16777217就不行了,表示不了,最后的1丢弃,就跟16一样了,也是1.0000x2^24。所有+1后不变。
可以看到16777218又可以精确表示了。
FLT_EPSILON 是 1.192092896e-07F,可以发现就是2^-23。以前以为EPSILON是最小的正浮点数,其实不是,可以看到16777215到16777216,相差的数是5.96e-08F,显然比EPSILON小。
EPSILON是个特殊的数,但不是最小的正浮点数,最小正浮点数是FLT_TRUE_MIN 1.401298464e-45F。