浮點數精度對程式設計使用的影響

2022-09-01 19:33:09 字數 1458 閱讀 3768

浮點數在計算機程式設計中一定會使用,然而使用中會有很多坑。最近做機械臂就被跳到坑里了。機械臂三自由度反解出來的cos值比1大一點點,1.00000...4。就是這一點點,坑了我一晚上,坑了師兄一上午。計算公式沒問題,求解程式沒問題,就是算出來的值有問題!後來才反應到是浮點數儲存造成的。

舉乙個最簡單的浮點數儲存影響的例子。

double targetvalue = 0.21

;double counter = 0

;int

main()

return0;

}

上面的程式,按照我們想想的,while迴圈將執行21次,之後counter和targetvalue相等,迴圈結束。

但是事實上,執行的時候並不是這樣。這裡我擷取幾個vs除錯的變數值來說明。

首次進入迴圈前,可以看到targetvalue的值並不是我們設定的0.21,而是0.20999...

在每次相加時,counter也不是加0.01,而是和0.01差距很小的乙個數,經過20次相加之後並不是0.2,而有差距。

當相加21次時,兩個數並不相等,所以無法退出迴圈。

可以看出,浮點數並不如我們認為的那麼精確。實際上,造成這個的原因是因為計算機的儲存機制造成的。計算機使用二進位制儲存資料,那麼對於0.21這個數,下面是轉換的過程,乘二取整法。

0.21*2=0.42 整數為0 -> 0.0

0.42*2=0.84 整數為0 -> 0.00

0.84*2=1.68 整數為1 -> 0.001

0.68*2=1.36 整數為1 -> 0.0011

0.36*2=0.72 整數為0 -> 0.00110

最後可以表示為:

0.0011010111000010…

可以看出,轉換成二進位制之後,是乙個無限的數,不能精確的表示出來。所以就造成了這個bug。這也是我們程式中,cos算出來超過1一點點的原因。我在matlab裡還原了c++的演算法,matlab計算出的數值就是1,沒有任何小數。

對於上面比較的問題,很多人都知道解決方法,那就是兩個浮點數求差,差值很小就認為相等。程式如下:

double targetvalue = 0.21

;double counter = 0

;int

main()

return0;

}

關於cos計算的bug,我最後採取的手段是將浮點數保留5位小數,精度能夠符合我們的要求,而且不會被浮點數儲存影響。

計算機上的坑真的多,爭取畢業前多踩,多填坑。

浮點數精度問題

一 例子 首先我們去編譯器試試 double a 1.9 通過新增監視檢視a的值 會發現a的值是1.8999999 二 開始今天的學習 在最開始學c 的時候並沒有對浮點數進行很深入的學習,認為浮點不就是小數嘛,首先在c 的巨集裡面有 flt max 和 flt min 的定義,float是四位元組的...

浮點數精度之謎

話要從業務 裡的bug說起,大致過程是前端運算 2.07 1 之後結果卻是1.0699999999999998,老司機們都知道是浮點數運算的精度丟失導致的,在檢視了下具體 果然處理不當。因此我深究一番,並誕生了此文。此處重點強調兩個認識誤區 首先不得不說說浮點數的表示方法,任何數在計算機面前都會被處...

PHP 浮點數的精度

浮點數的精度有限。儘管取決於系統,php 通常使用 ieee 754 雙精度格式,則由於取整而導致的最大相對誤差為 1.11e 16。非基本數 算可能會給出更大誤差,並且要考慮到進行復合運算時的誤差傳遞。此外,以十進位制能夠精確表示的有理數如 0.1 或 0.7,無論有多少尾數都不能被內部所使用的二...