matlab的floor函數是否有bug?
如圖,同學在用matlab編程的時候偶然發現的這個問題。我用自己的r2009b版本試了一遍也存在把29取整取成28的現象,而且試驗其他數就沒有這個問題。這是否是內置floor函數的一個bug?-----------------感謝大家的回答,請問在編程時應當養成一些怎樣的習慣以避免碰到這類問題,導致程序出bug呢?
&>&> format long
&>&> 0.29*100
ans =
28.999999999999996
&>&> 0.58*100
ans =
57.999999999999993
很多回答已經提到了,這是浮點小數表示精度的問題。類似的問題還有很多:
FAQ - MATLAB Wiki但是如何避免呢?
匿名用戶提到的用sym變數是一個方法,即floor(sym(0.29)*100),或者類似的方法。
另外一個方法就是手動用eps函數設置精度了,比如floor(0.29*100+eps(100))。baffling... rounding error of not so small numbers
一般來講,有意識地設置精度應該是一個良好的習慣。感覺原來學C的時候這個問題尤其突出,而MATLAB里遇到的情況其實不多,久而久之已經被MATLAB慣壞了……floor(0.29*100)=floor(28.999**)=28因為小數部分是由若干個1/2^k的和來表示的(0.625=1/2+1/8)但不難發現絕大多數的小數部分都沒有辦法做到(換言之,必須得無限項的和才能相等)而計算機存儲一個數據給的位置是定的,因此丟掉了後面的數據而存在誤差,因此計算機中0.29=0.2899***
計算機只認識0和1 !!!
整數轉為二進位一點沒問題,數值不存在一丁點損失。
但是對於小數,計算機只能通過2的負次冪無限逼近。
那0.29怎麼逼近呢?
2^-2 = 0.25 差0.04,繼續拼湊
2^-5 = 0.03125 差0.00875,繼續拼湊
。。。
。。。
最後計算機只能計算出一個無限逼近0.29的值,這個逼近的計算過程是循環過程,遇到剛好能湊齊的,直接break。但是如果遇到這樣逼近不了的就會無限循環下去。
所以才有了精度這個標準,如果在計算的過程中如果『『差』的值在這個精度範圍之內,那就break
同樣的,計算機計算開方也是湊出來的這不是bug,只是精度問題,由於二進位限制,幾乎所有語言的float類型都是只能精確到某些位.
舍入誤差
手頭沒matlab.
你試試floor(sym(0.29*100))或者
floor(sym("0.29*100"))看能不能解決問題.很奇怪,matlab原來在這個時候不是精確求解。
我一直以為matlab和mathematica這倆都是精確求解數值的。
原因上面都說了,是二進位和十進位換算問題。
你可以測試下 29 / 100 * 100 看看是多少。推薦閱讀:
※用於數學建模 安裝matlab 2014 需要安裝哪些組件?
※為什麼不少程序員認為Matlab的語言設計不優雅甚至比較丑?能否舉出一些例子來說明?
※matlab把數值數組轉成分立的字元組成的元胞數組?
※初學matlab需要什麼基礎嗎?