在java中不管是float還是double在進(jìn)行計(jì)算的時(shí)候都會(huì)有精度不準(zhǔn)的問(wèn)題如下例子:
@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é)果
我們會(huì)發(fā)現(xiàn)實(shí)際結(jié)果會(huì)比我們想要的結(jié)果多,如果這樣在進(jìn)行對(duì)金錢的計(jì)算時(shí)就會(huì)出現(xiàn)多收或者少收的結(jié)果,這樣肯定是有問(wèn)題的
下面我們來(lái)說(shuō)一下java里的BigDecimal類,這個(gè)類是java專門用于錢運(yùn)算的類,先看下面例子:
@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進(jìn)行兩個(gè)float或者double運(yùn)算的時(shí)候還是會(huì)出現(xiàn)精度不準(zhǔn)的問(wèn)題。
進(jì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.
*/
官方注釋說(shuō)明了BigDecimal的double構(gòu)造器會(huì)出現(xiàn)不可預(yù)測(cè)的問(wèn)題
下面就來(lái)看一下另外一個(gè)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)造器就不會(huì)出現(xiàn)不可預(yù)測(cè)的問(wèn)題
例子:
@Test
public void test3() {
BigDecimal b1 = new BigDecimal("0.05");
BigDecimal b2 = new BigDecimal("0.01");
System.out.println(b1.add(b2));
}
上述代碼輸出結(jié)果:

結(jié)果