你可能在寫程式的時候遇過這個問題:明明 0.1 加上 0.2 就應該是 0.3 啊,怎麼電腦算出來卻是 0.30000000000000004 或是類似的奇怪數字?別擔心,這不是你的程式碼壞掉了,也不是電腦算術不好,這背後其實牽扯到電腦儲存數字的特殊方式——浮點數 (Floating-point number)。
電腦的「二進位」世界 我們人類習慣用十進位(0到9)來計算,但電腦只認識兩種數字:0 和 1,也就是所謂的二進位。當我們給電腦一個十進位數字時,它會想辦法把這個數字轉換成二進位來儲存。
想像一下,十進位的小數像是 1/10=0.1、1/4=0.25 等等。有些小數可以很精確地用分數表示,例如 1/4 在二進位就是 0.01 2 (0×2 0 +0×2 −1 +1×2 −2 =0.25)。
麻煩的「無限循環小數」 問題來了!就像十進位中 1/3 是無限循環小數 0.333… 一樣,在二進位中,有些我們看起來很簡單的十進位小數,轉換成二進位後卻會變成無限循環小數。
舉例來說,0.1 和 0.2 轉換成二進位後,都是無限循環小數:
0.1 10 =0.0001100110011… 2
0.2 10 =0.001100110011… 2
空間有限的「儲存格」 電腦儲存數字的空間是有限的,就像我們在紙上寫無限循環小數時,總會遇到寫不下的時候。當電腦遇到無限循環的二進位小數時,它只能在某個地方截斷,只保留一定位數的數字。
這就像是你把 1/3 寫成 0.333,雖然很接近真實值,但終究不是 1/3 本身。這個截斷的過程就會產生微小的誤差。
誤差的累積 當 0.1 和 0.2 這兩個帶有微小誤差的數字相加時,這些誤差也會跟著一起相加,導致最終的結果 0.1+0.2 不再精確等於 0.3,而是一個非常接近 0.3 但帶有微小偏差的數字,例如 0.30000000000000004。
那該怎麼辦? 知道這個問題後,我們在程式設計時就有幾種處理方式:
避免直接比較浮點數: 永遠不要直接判斷兩個浮點數是否「相等」,因為它們可能因為誤差而略有不同。比較時可以判斷它們的差值是否小於一個極小的數 (例如:abs(a - b) < epsilon)。 使用高精度數字函式庫: 如果你需要非常精確的計算,可以考慮使用專門處理高精度數字的函式庫(例如 Python 的 decimal 模組),它們會用不同的方式來儲存和運算數字,以減少浮點數誤差。 轉換成整數運算: 如果你的數字都是固定小數位數,可以考慮先將它們乘以一個倍數,轉換成整數進行運算,最後再除回來。例如,0.1+0.2 可以變成 (1×10)+(2×10) 之後再除以 10。 希望這篇淺顯易懂的解釋,讓你對程式中 0.1 + 0.2 不等於 0.3 的問題有了更深入的了解。下次再遇到這種情況,你就會知道這是浮點數的正常「行為」,而不是程式錯誤囉!
0 留言
發表留言