在java中不管是float還是double在進行計算的時候都會有精度不準的問題如下例子:
@Test
public void test1() {
System.out.println(0.05 + 0.01);
System.out.println(1.0 - 0.42);
System.out.println(4.015 * 100);
System.out.println(123.2 / 100);
}
上述代碼輸出結(jié)果:
結(jié)果
我們會發(fā)現(xiàn)實際結(jié)果會比我們想要的結(jié)果多,如果這樣在進行對金錢的計算時就會出現(xiàn)多收或者少收的結(jié)果唁情,這樣肯定是有問題的
下面我們來說一下java里的BigDecimal類敢靡,這個類是java專門用于錢運算的類蝶锋,先看下面例子:
@Test
public void test2() {
BigDecimal b1 = new BigDecimal(0.05);
BigDecimal b2 = new BigDecimal(0.01);
System.out.println(b1.add(b2));
}
上述代碼輸出結(jié)果:
結(jié)果
可以看到使用Bigdecimal進行兩個float或者double運算的時候還是會出現(xiàn)精度不準的問題。
進入Bigdecimal類查看它的double構(gòu)造器:
/* The results of this constructor can be somewhat unpredictable.
* One might assume that writing {@code new BigDecimal(0.1)} in
* Java creates a {@code BigDecimal} which is exactly equal to
* 0.1 (an unscaled value of 1, with a scale of 1), but it is
* actually equal to
* 0.1000000000000000055511151231257827021181583404541015625.
* This is because 0.1 cannot be represented exactly as a
* {@code double} (or, for that matter, as a binary fraction of
* any finite length). Thus, the value that is being passed
* <i>in</i> to the constructor is not exactly equal to 0.1,
* appearances notwithstanding.
*/
官方注釋說明了BigDecimal的double構(gòu)造器會出現(xiàn)不可預(yù)測的問題
下面就來看一下另外一個BigDecimal構(gòu)造器String構(gòu)造器绷落。
先看官方注釋:
/*
* <p><b>Examples:</b><br>
* The value of the returned {@code BigDecimal} is equal to
* <i>significand</i> × 10<sup> <i>exponent</i></sup>.
* For each string on the left, the resulting representation
* [{@code BigInteger}, {@code scale}] is shown on the right.
*/
而String構(gòu)造器就不會出現(xiàn)不可預(yù)測的問題
例子:
@Test
public void test3() {
BigDecimal b1 = new BigDecimal("0.05");
BigDecimal b2 = new BigDecimal("0.01");
System.out.println(b1.add(b2));
}
上述代碼輸出結(jié)果:
結(jié)果