js,java,浮點數運算錯誤及應對方法

SherylF25 8年前發布 | 9K 次閱讀 Java Java開發 JavaScript

一.浮點數為什么會有運算錯誤

IEEE 754 標準規定了計算機程序設計環境中的二進制和十進制的浮點數自述的交換、算術格式以及方法.

現有存儲介質都是2進制。2進制的進制基數是2,那么一個數字只要被因素包含大于2的質數的數除,都會產生無限循環小數。無限循環小數和無理數都無法,和非無限循環的有理數一起用同一種方式存儲到存儲介質上的同時還保持計算的兼容性。

對于無限循環小數,可以設計一種格式存儲到介質上,但是同時又要和非無限循環的有理數能夠計算,效率應該會變得非常低下。 對于無理數,小數位的數字沒有規律可循,所以根本無法保存精確值,只能保存近似值。

高精度計算,一般可以將數字轉發成string, 去掉小數點,按位計算再保存回string,再加回小數點。

二.錯誤舉例

document.write (0.01 + 0.05);  //輸出結果為0.060000000000000005

document.write (0.09 + 0.01);  //輸出結果為0.09999999999999999

document.write(11*22.9);     //輸出結果為251.89999999999998

三.js如何應對

擴大倍數法:有多少位小數就擴大10的n次方

document.write((0.01*100+0.09*100)/100); //輸出結果為0.1

四舍五入法:

document.write((0.01+0.09).toFixed(2)); //保留2位小數,輸出結果為0.10

document.write(Math.round((0.01+0.09)*100)/100); //輸出結果為0.1

四.java如何應對

擴大倍數法:有多少位小數就擴大10的n次方

System.out.println((0.01*100+0.09*100)/100); //輸出結果為0.1

四舍五入法:

System.out.println(Math.rint(0.01*100+0.09*100)/100); //輸出結果為0.1

System.out.println(Math.round(0.01*100+0.09*100)/100); //輸出結果為0.1

System.out.println(new  BigDecimal(0.099).setScale(2,  RoundingMode.HALF_UP).doubleValue());  //輸出結果為0.10

備注: Java 支持7中舍入法

1、 ROUND_UP:遠離零方向舍入。向絕對值最大的方向舍入,只要舍棄位非0即進位。

2、 ROUND_DOWN:趨向零方向舍入。向絕對值最小的方向輸入,所有的位都要舍棄,不存在進位情況。

3、 ROUND_CEILING:向正無窮方向舍入。向正最大方向靠攏。若是正數,舍入行為類似于ROUND_UP,若為負數,舍入行為類似于ROUND_DOWN。Math.round()方法就是使用的此模式。

4、 ROUND_FLOOR:向負無窮方向舍入。向負無窮方向靠攏。若是正數,舍入行為類似于ROUND_DOWN;若為負數,舍入行為類似于ROUND_UP。

5、 HALF_UP:最近數字舍入(5進)。這是我們最經典的四舍五入。

6、 HALF_DOWN:最近數字舍入(5舍)。在這里5是要舍棄的。

7、 HAIL_EVEN:銀行家舍入法。銀行家舍入法.

 

來自:http://www.cnblogs.com/ooo0/p/5921559.html

 

 本文由用戶 SherylF25 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!