“我們人類的算術,有十個數字,從0到9,這個就是十進制。而在計算機的世界裏,就只有0和1兩個數字,這就是二進制。”小朱說,這個轉換的過程,詳細來說,就是壹個數字的整數部分除以2,取余數;小數部分乘以2取整數的方法。 以14.52為例,整數部分是14:14/2=7余0 7/2=3余1 3/2=1余1 1/2=0余1 所以,14在二進制裏就是1110。 小數部分是0.52: 0.52×2=1.04 整數1 0.04×2=0.08 整數0 0.08×2=0.16 整數0 0.16×2=0.32 整數0 小數部分和整數部分略有不同,小數部分很可能無窮無盡,但為了方便起見,我們只進行4次運算。於是,我們得到小數部分的結果是1000。 所以,14.52在二進制裏是1110.1000 以此類推,14.49在二進制裏是1110.0111 這樣,14.52-14.49通過二進制運算就是1110.1000-1110.0111=0.0001 然後,我們再把它轉換回十進制(二進制轉換為十進制的公式為:ABC.XYZ=A×2"2+ B×2"1+C×2"0+X×2"-1+Y×2"-2+Z×2"-3,計算時,把相應的數字替換公式中的A、B、C等符號),得到的結果是0.0625。 可能有細心的讀者已經發現,我們得到的結果竟然與真實的結果相差巨大,甚至比安卓的計算器還要糟糕。難道我們的算法錯了?其實不然,小朱說,這與我們在小數部分進行運算的次數有關。如果我們多運算幾次,精確度就會大為提高。像安卓計算機裏得到的0.09999的數字,基本上我們在小數部分計算到接近30次以後,就可以實現。
■ 這不是安卓才有的bug 小朱說,之前我們已經提到,這個在當今的計算機領域幾乎無法避免。但我們也可以通過壹些技術手段來進行規避。比如,可以把有小數點的數字先放大,把它變成整數進行運算,之後再除以相應數字,最終就會得到精確的結果;或者事先確定要精確到的位數,然後計算到這壹位之後,進行四舍五入,效果也是壹樣的。 在采訪中,記者發現,這個問題並非安卓的計算器獨有,包括百度計算器,甚至是Windows操作系統自帶的計算器,也會出現這樣的現象。朱寧表示,那些能得到精確結果的計算器很可能就是利用了上面的方法,進行了優化。“平時碰到了也不要大驚小怪,就當個笑話吧。”他說。
Java long 處理減法會出現減不盡的情況!這跟Java的問題!可能設計時忽略吧,屬於低級bug!
類似的還有:14.52-14.49=0.029999,而不是0.03;
8.03-7.96=0.069999等等