為什麼3/10-3*0.1不等於零?

matlab上算的不等於零,

在提問之前我還是百度一下吧,結果亮點出現了。


我猜的

matlab默認類型好像是double,這裡姑且先將它看作double類型,1位符號,11位指數,52位小數,小數部分省略1。

3/10=11/1010=1.(0011)*2^(-10)

括弧內為循環

那麼3/10對應的小數位是

0011001100110011001100110011001100110011001100110011

我感覺機器應該是截斷,不會四捨五入。

3*0.1要先將*左右變成double

3*0.1=11.0*0.0(0011)=1.1*2^(1)*1.(1001)*2^(-100)

0.1的小數位是

1001100110011001100110011001100110011001100110011001

不四捨五入的情況下是

1.1*1.1001100110011001100110011001100110011001100110011001*2^(1-100)

=1.001100110011001100110011001100110011001100110011001011*2(-10)

那麼3*0.1小數位是

0011001100110011001100110011001100110011001100110010

相減得

0000000000000000000000000000000000000000000000000001

指數部分是(-10),結果表示成2進位小數是

1*2(-110100)

這個數碰巧就是5.551115*10^(-17),但是符號不對。

然後我考慮了一下四捨五入情況

假設會四射五入的話3/10小數位是

0011001100110011001100110011001100110011001100110011

假設四捨五入的話0.1小數位是

1001100110011001100110011001100110011001100110011010

四捨五入情況下乘法是

1.1*1.1001100110011001100110011001100110011001100110011010*2^(1-100)

=1.001100110011001100110011001100110011001100110011001110*2(-2)

3*0.1小數位是

0011001100110011001100110011001100110011001100110100

相減得

-0000000000000000000000000000000000000000000000000001

指數部分是(-10),結果表示成2進位小數是

-1*2(-110100)

那麼這個數就是

-5.551115*10^(-17)

我也是才知道,double是四捨五入的。


@天涯行客

武牧解釋得挺清楚了,關於浮點運算的其他相關信息可以參見:

What Every Computer Scientist Should Know About Floating-Point Arithmetic


果然還是AlphaDog家的靠譜。


大型模型這個問題煩死人。為了保證方程組有解,往往最後一個方程就是x+y=z,必須寫成10000x+10000y=10000Z。


推薦閱讀:

電腦內存不足,matlab處理不了80000*80000這樣的大矩陣,跪求解決辦法?
對於廣大程序員來說,《演算法導論》不看數學證明只看其餘的部分合適嗎?
為什麼鍵盤上的橫排數字鍵 0 在 9 的右邊,而不是在 1 的左邊?
為什麼內存,顯卡等組合在一起,通電之後可以變成畫面呈現出來?一開始科學家是怎麼發現的?
參加微軟校園Hackathon是怎樣的體驗?

TAG:計算機 | MATLAB | 計算器 | 計算科學 |