天天看點

簡單了解BigDecimal.valueof(Double t)與BigDecimal.valueof(String t)的差別

我也是簡單的了解一下

先用簡單的代碼展示一下

Java代碼:

簡單了解BigDecimal.valueof(Double t)與BigDecimal.valueof(String t)的差別

上面的代碼主要的差別在于

初始化BigDecimal時形參是double、String和float的差別

從上面可以看到,當double 和 float 時,實際儲存的值并不是是準确的0.99,這是為什麼呢

大緻的原因是:

         BigDecimal(double val)将會把double型二進制浮點型值精确的轉換成十進制的BigDecimal。

        你可能認為java中用new BigDecimal(0.1)建立的BigDecimal應該等于0.1(一個是1的無精度的值,一個是有精度的值),但實際上精确的是等于0.1000000000000000055511151231257827021181583404541015625。這是因為0.1不能被double精确的表示(下面大概描述一下原理)。是以,傳入構造函數的值不是精确的等于0.1。

       對與float也是同樣的道理。首先此函數會自動進行精度擴充,将float類型的0.99轉成double類型的,因為0.99本身就是無法用二進制表示的,也就說無論你的精度是多少位,都無法用二進制來精确表示0.99,或者你用二乘來判斷(0.99*2=1.98 0.98*2=1.960.96*2=1.92 。。。永遠無法得到一個整數)。這就是二進制計算機的缺點,就如同十進制也也無法表示1/3,1/6一樣。

        是以在0.99f轉成double時,進行了精度擴充,變成了0.9900000095367432,而接着轉成字元串,最後轉成BigDecimal.

總結:

        是以在當遇到需要涉及到精确計算的時候,如上面代碼所示,要注意該構造函數是一個精确的轉換,它無法得到與先調用Double.toString(double)方法将double轉換成String,再使用BigDecimal(String)構造函數一樣的結果。如果要達到這種結果,應該使用new BigDecimal(Stringvalue) 或 BigDecimal.valueof( double value)

繼續閱讀