日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
踩坑日記:BigDecimal四大坑,真的會用BigDecimal?

一、前言

最近在項(xiàng)目中使用BigDecimal存儲訂單的數(shù)量,數(shù)據(jù)庫保留三位小數(shù)。需求是數(shù)量變化了就會有其他操作,頭腦發(fā)熱順手寫了個equals進(jìn)行判斷是不是相等!

成都創(chuàng)新互聯(lián)專注于太康網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供太康營銷型網(wǎng)站建設(shè),太康網(wǎng)站制作、太康網(wǎng)頁設(shè)計(jì)、太康網(wǎng)站官網(wǎng)定制、成都微信小程序服務(wù),打造太康網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供太康網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

后來怎么測都是不相等!百思不得其解,看了一下equals方法才知道!

BigDecimal值的比較官方推薦是compareTo的,如果數(shù)據(jù)庫沒有保留小數(shù),用equals是沒問題,但是不建議,非常不建議??!

今天就總結(jié)一下BigDecimal使用時(shí)需要注意的點(diǎn)!

二、BigDecimal在理解

BigDecimal是Java編程語言中的一個類,屬于java.math包,用于進(jìn)行高精度的十進(jìn)制數(shù)計(jì)算。它提供了對任意精度的十進(jìn)制數(shù)進(jìn)行精確計(jì)算的能力,適用于需要保持精度和執(zhí)行準(zhǔn)確計(jì)算的場景。

與基本的浮點(diǎn)數(shù)類型(如float和double)不同,BigDecimal使用基于整數(shù)的表示方法,通過存儲和處理數(shù)值的每一位來避免精度丟失。這使得它可以表示極大或極小的數(shù)字,并執(zhí)行準(zhǔn)確的計(jì)算。

BigDecimal在金融領(lǐng)域、貨幣計(jì)算、稅務(wù)計(jì)算、精確計(jì)算需求以及其他需要保持精度和執(zhí)行準(zhǔn)確計(jì)算的場景中廣泛應(yīng)用。

「當(dāng)然要注意」:

BigDecimal對象是不可變的,這意味著一旦創(chuàng)建就不能修改其值。每個操作都會產(chǎn)生一個新的BigDecimal對象作為結(jié)果。

由于BigDecimal是一個對象,并且執(zhí)行計(jì)算時(shí)需要更多的內(nèi)存和處理時(shí)間,與使用原生數(shù)據(jù)類型相比,它可能會稍微降低性能。因此,在大量計(jì)算或?qū)π阅芤筝^高的情況下,需要權(quán)衡使用BigDecimal的優(yōu)勢和劣勢。

三、BigDecimal注意點(diǎn)

1、BigDecimal使用equals

這就是小編最近需要的,我們還是要提高自己的編碼規(guī)范哈,不要學(xué)小編,equals用習(xí)慣了,看見比較就用!

當(dāng)然也不用使用 == != 來比較哈??!

我們來個例子感受一下哈!

BigDecimal dbNum = new BigDecimal("2.000");

BigDecimal num = new BigDecimal("2");
 if (dbNum.equals(num)) {
     System.out.println("=========相等我就操作========");
 }else {
     System.out.println("=========不相等就忽略========");
 }

 BigDecimal dbNum1 = new BigDecimal("2");
 if (dbNum1.equals(num)) {
     System.out.println("=========相等我就操作========");
 }else {
     System.out.println("=========不相等就忽略========");
 }

我們從源碼來看一下這個equals內(nèi)部到底是怎么比較的:

我們看到BigDecimal里重寫了equals方法!

前面簡單的就不說什么意思了,我們挑重點(diǎn)說一下:

scale != xDec.scale:這是比較兩個數(shù)的精度長度是否相等,長度不一致直接返回false,這就是我們例子返回false的原因!

我們打斷點(diǎn)可以看到一個是3位精度,一個0位!

long s = this.intCompact; long xs = xDec.intCompact; :這倆放一起說:

表示 BigDecimal 對象的緊湊表示形式,這個又分為jdk8之前和之后

在 JDK 1.8 之前的版本中,BigDecimal 內(nèi)部使用一個 int 數(shù)組來表示大整數(shù)。每個元素都代表了 BigDecimal 的一部分位數(shù)。這種表示方式需要額外的內(nèi)存空間,并且對于小數(shù)和較小的整數(shù)來說是不必要的。

為了優(yōu)化性能和節(jié)省內(nèi)存,JDK 1.8 引入了 intCompact 屬性,它將 BigDecimal 內(nèi)部的表示形式轉(zhuǎn)換為一個 long 值。這個 long 值可以直接存儲整數(shù)值,而對于較大的數(shù)字,則使用溢出(overflow)和膨脹(inflation)機(jī)制進(jìn)行處理。

具體而言,當(dāng) BigDecimal 對象的值可以用 long 類型表示時(shí),intCompact 將存儲該長整型值。如果值超過 long 類型的范圍,則會使用其他方式進(jìn)行存儲,例如使用 intVal 字段來存儲 int 數(shù)組。

為了形象,我們把第二次比較的兩個數(shù)都變?yōu)椋?.0,經(jīng)過intCompact后,變?yōu)?0來進(jìn)行后續(xù)操作! 如果超過Long的最大值就會:使用溢出(overflow)和膨脹(inflation)機(jī)制進(jìn)行處理,這里就不展開看了,感興趣的可以模擬打斷點(diǎn)查看哈!

源碼:

@Override
public boolean equals(Object x) {
    if (!(x instanceof BigDecimal))
        return false;
    BigDecimal xDec = (BigDecimal) x;
    if (x == this)
        return true;
    if (scale != xDec.scale)
        return false;
    long s = this.intCompact;
    long xs = xDec.intCompact;
    if (s != INFLATED) {
        if (xs == INFLATED)
            xs = compactValFor(xDec.intVal);
        return xs == s;
    } else if (xs != INFLATED)
        return xs == compactValFor(this.intVal);

    return this.inflated().equals(xDec.inflated());
}

解決方案就是:使用compareTo,compareTo方法實(shí)現(xiàn)了Comparable接口,準(zhǔn)備的比較的兩者! 有興趣可以debug看看compareTo方法!這里就不給大家展示了??!

2、BigDecimal初始化

這個基本上大家都會注意,用字符串或整數(shù)初始化:為避免浮點(diǎn)數(shù)轉(zhuǎn)換引起的精度丟失,最好使用字符串或整數(shù)來初始化BigDecimal對象!double、float類型只能保留有限的有效數(shù)字,分別是15個左右7、8個,我們寫個例子就明白了!

我們寫上IDEA都看不下去要提示你可以優(yōu)化,Alt+Enter讓IDEA來解決吧?。?/p>

BigDecimal bigDecimal2 = new BigDecimal("0.11");

BigDecimal bigDecimal = new BigDecimal(0.11);

System.out.println(bigDecimal);
System.out.println(bigDecimal2);

3、BigDecimal精度問題

我們在使用BigDecimal 進(jìn)行計(jì)算的時(shí)候,一定要保留小數(shù),基本上所有的計(jì)算需求都會讓你保留幾位小數(shù)。沒有的話得到無限小數(shù)就會報(bào)錯異常:ArithmeticException!

保留小數(shù)的規(guī)則這里就不展開說了,大家根據(jù)自己需要去看api就可以了!

BigDecimal bigDecimal2 = new BigDecimal("10");

BigDecimal bigDecimal = new BigDecimal("3");

System.out.println(bigDecimal2.divide(bigDecimal));

4、BigDecimal多余0

這個就是前面最開始說的,我們保留的位數(shù)很多,有的前端展示又不想看到!這時(shí)就要把多余的0去掉!

這其實(shí)不算坑了,這算是優(yōu)化顯示哈!

BigDecimal bigDecimal1 = new BigDecimal("199.100");
System.out.println(bigDecimal1);
System.out.println(bigDecimal1.stripTrailingZeros());

四、總結(jié)

我們來在總結(jié)有哪些注意事項(xiàng)哈:

  • BigDecimal比較大小的時(shí)候要使用compareTo();
  • BigDecimal用字符串或整數(shù)初始化;
  • BigDecimal計(jì)算時(shí)盡量指定保留精度位數(shù);
  • 按需去除多余0;
  • BigDecimal都是不可變的;

大家一定注意這些東西,特別是設(shè)計(jì)到錢的計(jì)算,一個不小心一個小目標(biāo)沒了!


分享名稱:踩坑日記:BigDecimal四大坑,真的會用BigDecimal?
分享地址:http://www.5511xx.com/article/cdiipoj.html