演示代碼
#include<stdio.h>
int main () {
double i;
for (i = 0; i != 1; i += 0.1) {
printf ("%lf\n", i);
}
return 0;
}
大家可以先猜想下結(jié)果。
結(jié)果

倒數(shù)第三行可以看到我強制退出了程序,否則會一直打印。為什么這樣呢?0.1累加十次之后,不應(yīng)該是1.0嗎?
原因
1、浮點數(shù)表示方法
根本原因是不清楚浮點數(shù)的表示方法。
- 二進制格式
先來說下浮點數(shù)的二進制格式,單精度浮點數(shù)采用32位bits表示,雙精度浮點數(shù)采用64位bits表示。分為三部分,符號位(S)、階碼(E)和尾數(shù)(M)。
single precision:1位符號位,8位階碼,23位尾數(shù)
double precision:1位符號位,11位階碼,32位尾數(shù)
符號位1表示負數(shù),0表示正數(shù)。
- IEEE754
IEEE754標準中,規(guī)格化的浮點數(shù)真值表示為:
x =(?1)s * (1.M) *2e
其中E = [e]移碼 - 1,階碼的移碼即把補碼標志位取反,為了能表示正負無窮大。由于尾數(shù)高位恒為1,所以只存儲浮點數(shù)位M。
- 舉個栗子
給出十進制數(shù)-4.25的機器碼,使用單精度
-4.25 = [-100.01]2,符號位為1,尾數(shù)為 1.0001,指數(shù)為2,
所以尾數(shù)域二進制碼
M = [000 1000 0000 0000 0000 0000]2
階碼
E = [2]移碼 - 1 = [1000 0010]2 - 1 = [1000 0001]
得到機器碼為
-4.5 = [1100 0000 1000 1000 0000 0000 0000 0000]2
結(jié)論
浮點數(shù)不能精確表示某些十進制數(shù),只能取無限近似值。將累加值換為0.5,則程序只打印兩次值。
示例代碼中的0.1的累加,則是其近似值的累加,所以不會命中 1 ,程序會一直執(zhí)行下去。