java中如何防止數(shù)字丟失精度(用于錢的運(yùn)算)

在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> &times; 10<sup>&nbsp;<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é)果

由此可以看出為了防止精度丟失要使用BigDecimal里的String構(gòu)造器

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容