浮點數陷阱 無法精確儲存0 1

2021-10-14 17:41:58 字數 1170 閱讀 2996

double x =

1.0/10;

double y =1-

0.9;

double z =

0.1+

0.2;

// 觀察x、y、z的結果

在計算機中,浮點數雖然表示的範圍大,但是浮點數有個非常重要的特點——浮點數常常無法精確表示。

例如,浮點數0.1在計算機中就無法精確表示,所以運算結果就會出現偏差。

如果你了解浮點數二進位制儲存機制,那麼就很簡單,二進位制只能精確儲存小數域是2的負指數冪及其線性組合的數。例如0.25、0.5…

如果你不了解,那麼一起來看…

0.1 = 1/24 + 1/25 + 1/28 +1/29+1/212+1/213…

0.110=0.0001100110011001100110011…2

這是乙個二進位制無限迴圈小數。

計算機記憶體有限,我們不能儲存所有的小數字數,所以在某個精度點直接捨棄,單精度精確到23位,雙精度精確到52位。

也就是說,0.1在計算機內部根本就不是精確的0.1,而是乙個有捨入誤差的0.1。當**被編譯或解釋後,0.1已經被四捨五入成乙個與之很接近的計算機內部數字,導致計算還沒開始,乙個很小的捨入錯誤就已經產生了。這也就是上面問題產生的根本原因。

關於浮點數的儲存機制請移步——浮點數揭秘——ieee754

不同行業,要求的精度不是線性的,我們允許(對結果無關緊要的)誤差存在,例如10.0001與10.001在鐵路工程師看來都是合格的。

雖然允許誤差存在,但是程式設計師在使用浮點數進行計算或邏輯處理時,稍不注意,就可能會問題。

記住,永遠不要直接比較兩個浮點數的大小,小心這個陷阱!

水平有限,如有錯誤之處,還請指正。

浮點數陷阱

剛在 演算法競賽 入門經典 中看到的,乙個浮點數陷阱,覺得蠻有意思的,所以發上來和大家分享一下。下面 執行的結果是什麼?includeint main 或許你會覺得輸出肯定是從0.0開始一直到10.0結束對吧。不過你上機執行一下就會發現,輸出陷入了死迴圈一樣,會一直不停的輸出。原因是,程式中的i永遠...

浮點數陷阱

在書上看到這樣的乙個程式 includeint main return 0 第一反應是乙個簡單的for迴圈,i每次增加0.1如何輸出,一直到i 10,迴圈結束。執行之後 程式進入死迴圈,說明 for i 0 i 10 i 0.1 中i 10終止條件沒有起作用,在for迴圈中加入兩條語句觀察i的值 f...

浮點數陷阱

陷阱1 cpp view plain copy print double i for i 0 i 10 i 0.1 printf 1lf n i double i for i 0 i 10 i 0.1 printf 1lf n i 程式會列印至10.0時結束迴圈嗎?不會。因為i永遠也不可能等於10,...