java bigDecimal and double
生活随笔
收集整理的這篇文章主要介紹了
java bigDecimal and double
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Java BigDecimal和double
BigDecimal是Java中用來表示任意精確浮點數運算的類,在BigDecimal中,使用unscaledValue × 10-scale來表示一個浮點數。其中,unscaledValue是一個BigInteger,scale是一個int。從這個表示方法來看,BigDecimal只能標識有限小數,不過可以表示的數據范圍遠遠大于double,在實際應用中基本足夠了。
下面提一下兩個精度問題: 問題一:BigDecimal的精度問題(StackOverflow上有個家伙問了相關的問題) System.out.println(new BigDecimal(0.1).toString()); // 0.1000000000000000055511151231257827021181583404541015625 System.out.println(new BigDecimal("0.1").toString()); // 0.1 System.out.println(new BigDecimal( Double.toString(0.1000000000000000055511151231257827021181583404541015625)).toString());// 0.1 System.out.println(new BigDecimal(Double.toString(0.1)).toString()); // 0.1分析一下上面代碼的問題(注釋的內容表示此語句的輸出)
第一行:事實上,由于二進制無法精確地表示十進制小數0.1,但是編譯器讀到字符串"0.1"之后,必須把它轉成8個字節的double值,因此,編譯器只能用一個最接近的值來代替0.1了,即0.1000000000000000055511151231257827021181583404541015625。因此,在運行時,傳給BigDecimal構造函數的真正的數值是0.1000000000000000055511151231257827021181583404541015625。 第二行:BigDecimal能夠正確地把字符串轉化成真正精確的浮點數。 第三行:問題在于Double.toString會使用一定的精度來四舍五入double,然后再輸出。會。Double.toString(0.1000000000000000055511151231257827021181583404541015625)輸出的事實上是"0.1",因此生成的BigDecimal表示的數也是0.1。 第四行:基于前面的分析,事實上這一行代碼等價于第三行 結論: 1.如果你希望BigDecimal能夠精確地表示你希望的數值,那么一定要使用字符串來表示小數,并傳遞給BigDecimal的構造函數。 2.如果你使用Double.toString來把double轉化字符串,然后調用BigDecimal(String),這個也是不靠譜的,它不一定按你的想法工作。 3.如果你不是很在乎是否完全精確地表示,并且使用了BigDecimal(double),那么要注意double本身的特例,double的規范本身定義了幾個特殊的double值(Infinite,-Infinite,NaN),不要把這些值傳給BigDecimal,否則會拋出異常。 問題二:把double強制轉化成int,難道不是扔掉小數部分嗎? int x=(int)1023.99999999999999; // x=1024為什么?原因還是在于二進制無法精確地表示某些十進制小數,因此1023.99999999999999在編譯之后的double值變成了1024。
所以,把double強制轉化成int確實是扔掉小數部分,但是你寫在代碼中的值,并不一定是編譯器生成的真正的double值。 驗證代碼: double d = 1023.99999999999999; int x = (int) d; System.out.println(new BigDecimal(d).toString()); // 1024 System.out.println(Long.toHexString(Double.doubleToRawLongBits(d))); // 4090000000000000 System.out.println(x); // 1024前面提過BigDecimal可以精確地把double表示出來還記得吧。
我們也可以直接打印出d的二進制形式,根據IEEE 754的規定,我們可以算出0x4090000000000000=(1024)。轉載于:https://www.cnblogs.com/yelongsan/p/4120913.html
總結
以上是生活随笔為你收集整理的java bigDecimal and double的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 后缀自动机在复习
- 下一篇: thinkphp的select和find