首先,在 A 部份 (第 5 行到第 11 行):
因為 1.25 以 float 來儲存於記憶體中,其 32 位元的內容為:
0 01111111 01000000000000000000000
又 1.25 以 double 來儲存於記憶體中,其 64 位元的內容為:
0 01111111111 0100000000000000000000000000000000000000000000000000
由此可知,1.25 剛好可以正確地被用二進位表示出來。因此,當第 8 行做 "相等" 的比較時,將會同時以 double 型態來做比較 (原為 float 型態的會被暫時轉換成 double 型態),因此當 32 位元的 1.25 (float 型態)被轉成 64 位元的 double 型態時,變成了:
0 01111111111 0100000000000000000000000000000000000000000000000000
其中,在上一行裡,紅色部份為轉換型態之後 (被擴大了),被補充上去的資料。因此,比較完之後,比較兩邊雙方確實完全相等,因此印出了「1」(真值)。
再來,我們看 B 部份 (第 13 行到第 19 行):
因為 1.27 以 float 來儲存於記憶體中,其 32 位元的內容為:
0 01111111 01000101000111101011100
又 1.27 以 double 來儲存於記憶體中,其 64 位元的內容為:
0 01111111111 0100010100011110101110000101000111101011100001010010
由此可知,1.27 無法被正確地以二進位來完整地表示出來 (上面的 float 格式的 mantissa 部份由於只能表示 23 個位元,但事實上,後面還有很多位元無法被表現出來)。因此,當 1.27 被以 float 的格式儲存到記憶體時,它是取最接近 1.27 的數值來儲存 (大約是 1.2699999809265137); 相同的情況也發生在 double 格式時,上圖的 d2 變數的執行結果印出了 1.270000000000000000..... 的原因乃是因為 printf() 在輸出時會自動為浮點數做必要的進位,事實上 d2 並不剛好等於 1.27。當第 16 行做 "相等" 的比較時,也是一樣,將會同時以 double 型態來做比較 (原為 float 型態的也會被暫時地轉換成 double 型態),因此當 32 位元的 1.27 (float 型態)被轉成 64 位元的 double 型態時,變成了:
0 01111111111 0100010100011110101110000000000000000000000000000000
其中,在上一行裡,紅色部份為轉換型態之後 (被擴大了),被補充上去的資料。因此,比較完之後,比較兩邊雙方確實不相等,因此印出了「0」假值)。
最後,我們看 C 部份 (第 21 行到第 29 行):
因為 1.2700001 (即變數 a) 以 float 來儲存於記憶體中,其 32 位元的內容為: (rounded; 即進位後結果)
0 01111111 01000101000111101011101
又 1.27000001(即變數 b) 以 float 來儲存於記憶體中,其 32 位元的內容為: (rounded; 即進位後結果)
0 01111111 01000101000111101011100
而 1.27 (即變數 c) 以 float 來儲存於記憶體中,其 32 位元的內容為: (rounded; 即進位後結果)
0 01111111 01000101000111101011100
由此可知,1.2700001 與 1.27000001 也是一樣無法被正確地以二進位來完整地表示出來 (上面的 float 格式的 mantissa 部份由於只能表示 23 個位元,但事實上,後面還有很多位元無法被表現出來)。因此,當 1.2700001 被以 float 的格式儲存到記憶體時,它是取最接近 1.2700001 的數值來儲存 (大約是 1.2700001001358032); 相同的情況也發生在 1.27000001 的 float 格式時。當第 25 行做 "相等" 的比較時,由上面所列出來的二進位表示法可以得知,變數 a 與變數 c 確實不相等,因此印出了「0」假值)。同時,當第 26 行做 "相等" 的比較時,變數 b 與變數 c 確實相等,因此印出了「1」這個真值)。
如此一來,你可以看出來為何 (1.2700001 != 1.27) 但是 (1.27000001 == 1.27) 的原因所在了。因此,在相當注重浮點數運算的應用程式中,要特別小心使用浮點數。