最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中BigDecimal除法使用不當(dāng)導(dǎo)致精度問題

 更新時(shí)間:2021年11月02日 15:39:45   作者:一灰灰  
本文主要介紹了Java中BigDecimal除法使用不當(dāng)導(dǎo)致精度問題,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

在使用BigDecimal的除法時(shí),遇到一個(gè)鬼畜的問題,本以為的精度計(jì)算,結(jié)果使用返回0,當(dāng)然最終發(fā)現(xiàn)還是使用姿勢(shì)不對(duì)導(dǎo)致的,因此記錄一下,避免后面重蹈覆轍

I. 問題拋出

在使用BigDecimal做高精度的除法時(shí),一不注意遇到了一個(gè)小問題,如下

@Test
public void testBigDecimal() {
    BigDecimal origin = new BigDecimal(541253);
    BigDecimal now = new BigDecimal(12389431);

    BigDecimal val = origin.divide(now, RoundingMode.HALF_UP);
    System.out.println(val);

    origin = new BigDecimal(541253);
    now = new BigDecimal(12389431.3);
    val = origin.divide(now, RoundingMode.HALF_UP);
    System.out.println(val);

    origin = new BigDecimal(541253.4);
    now = new BigDecimal(12389431);
    val = origin.divide(now, RoundingMode.HALF_UP);
    System.out.println(val);
}

上面的輸出是什么 ?
0
0
0.043686703610520937021487456961257

為什么前面兩個(gè)會(huì)是0呢,如果直接是 541253 / 12389431 = 0 倒是可以理解, 但是BigDecimal不是高精度的計(jì)算么,講道理不應(yīng)該不會(huì)出現(xiàn)這種整除的問題吧

我們知道在BigDecimal做觸發(fā)時(shí),可以指定保留小數(shù)的參數(shù),如果加上這個(gè),是否會(huì)不一樣呢?

BigDecimal origin = new BigDecimal(541253);
BigDecimal now = new BigDecimal(12389431);

BigDecimal val = origin.divide(now, 5, RoundingMode.HALF_UP);
System.out.println(val);

輸出結(jié)果為:
0.04369

所以說在指定了保留小數(shù)之后,則沒有問題,所以大膽的猜測(cè)一下,是不是上面的幾種case中,由于scale值沒有指定時(shí),默認(rèn)值不一樣,從而導(dǎo)致最終結(jié)果的精度不同呢?

簡(jiǎn)單的深入源碼分析一下,執(zhí)行的方式為 origin.divide(now, RoundingMode.HALF_UP);, 所以這個(gè)scale參數(shù)就瞄準(zhǔn)origin對(duì)象,而這個(gè)對(duì)象,就只能去分析它的構(gòu)造了,因?yàn)闆]有其他的地方使用

II. 源碼定位

1. 整形傳參構(gòu)造

分析下面這一行, 直接進(jìn)入源碼

BigDecimal origin = new BigDecimal(541253);

很明顯的int傳參構(gòu)造,進(jìn)去簡(jiǎn)單看一下

// java.math.BigDecimal#BigDecimal(int)
public BigDecimal(int val) {
    this.intCompact = val;
    this.scale = 0;
    this.intVal = null;
}

public BigDecimal(long val) {
    this.intCompact = val;
    this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
    this.scale = 0;
}

so,很明確的知道默認(rèn)的scale為0,也就是說當(dāng)origin為正數(shù)時(shí),以它進(jìn)行的除法,不現(xiàn)實(shí)指定scale參數(shù)時(shí),最終返回的都是沒有小數(shù)的,同樣看一眼,還有l(wèi)ong的傳參方式, BigInteger也一樣

2. 浮點(diǎn)傳參

接下來就是浮點(diǎn)的scale默認(rèn)值確認(rèn)了,這個(gè)構(gòu)造相比前面的復(fù)雜一點(diǎn),源碼就不貼了,太長(zhǎng),也看不太懂做了些啥,直接用猥瑣一點(diǎn)的方式,進(jìn)入debug模式,單步執(zhí)行

@Test
public void testBigDecimal() {
    BigDecimal origin = new BigDecimal(541253.0);
    BigDecimal now = new BigDecimal(12389431.1);
    BigDecimal tmp = new BigDecimal(0.0);
}

根據(jù)debug的結(jié)果,第一個(gè),scale為0; 第二個(gè)scale為29, 第三個(gè)scale為0

3. String傳參

依然是一大串的邏輯,同樣采用單步debug的方式試下

@Test
public void testBigDecimal() {
    BigDecimal origin = new BigDecimal("541253.0");
    BigDecimal now = new BigDecimal("12389431.1");
    BigDecimal t = new BigDecimal("0.0");
}

上面三個(gè)的scale都是1

4. 小結(jié)

對(duì)于BigDecimal進(jìn)行除法運(yùn)算時(shí),最好指定其scale參數(shù),不然可能會(huì)有坑
對(duì)于BigDecimla的scale初始化的原理,有待深入看下BigDecimal是怎么實(shí)現(xiàn)的

最后貼一張乘法的圖作為收尾

到此這篇關(guān)于Java中BigDecimal除法使用不當(dāng)導(dǎo)致精度問題的文章就介紹到這了,更多相關(guān)Java BigDecimal除法精度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Redisson實(shí)現(xiàn)注解式分布式鎖的示例代碼

    基于Redisson實(shí)現(xiàn)注解式分布式鎖的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何基于Redisson實(shí)現(xiàn)注解式分布式鎖,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的可以了解一下
    2023-07-07
  • 關(guān)于BigDecimal類型之間比較問題

    關(guān)于BigDecimal類型之間比較問題

    這篇文章主要介紹了關(guān)于BigDecimal類型之間比較問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • VsCode搭建Spring Boot項(xiàng)目并進(jìn)行創(chuàng)建、運(yùn)行、調(diào)試

    VsCode搭建Spring Boot項(xiàng)目并進(jìn)行創(chuàng)建、運(yùn)行、調(diào)試

    這篇文章主要介紹了VsCode搭建Spring Boot項(xiàng)目并進(jìn)行創(chuàng)建、運(yùn)行、調(diào)試 ,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • java后端操作樹結(jié)構(gòu)的案例代碼

    java后端操作樹結(jié)構(gòu)的案例代碼

    這篇文章主要介紹了java后端操作樹結(jié)構(gòu),樹結(jié)構(gòu)的三種組裝方式(遞歸.雙層for循環(huán),map),通過實(shí)例代碼介紹了使用遞歸查詢某個(gè)節(jié)點(diǎn)所在的樹結(jié)構(gòu),需要的朋友可以參考下
    2023-10-10
  • redis.clients.jedis.exceptions.JedisMovedDataException異常解決

    redis.clients.jedis.exceptions.JedisMovedDataException異常解決

    redis.clients.jedis.exceptions.JedisMovedDataException?異常是在使用?Jedis?客戶端與?Redis?集群進(jìn)行交互時(shí)發(fā)生的,下面就來介紹一下解決方法,感興趣的可以了解一下
    2024-05-05
  • Idea2020.2創(chuàng)建JavaWeb項(xiàng)目(部署Tomcat)方法詳解

    Idea2020.2創(chuàng)建JavaWeb項(xiàng)目(部署Tomcat)方法詳解

    這篇文章主要介紹了Idea2020.2創(chuàng)建JavaWeb項(xiàng)目(部署Tomcat)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java基礎(chǔ)之序列化與反序列化詳解

    Java基礎(chǔ)之序列化與反序列化詳解

    這篇文章主要介紹了Java基礎(chǔ)之序列化與反序列化詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-04-04
  • java設(shè)計(jì)模式之工廠方法詳解

    java設(shè)計(jì)模式之工廠方法詳解

    這篇文章主要為大家詳細(xì)介紹了java設(shè)計(jì)模式之工廠方法的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • 關(guān)于Java中XML Namespace 命名空間問題

    關(guān)于Java中XML Namespace 命名空間問題

    這篇文章主要介紹了Java中XML Namespace 命名空間,XML命名空間是由國際化資源標(biāo)識(shí)符 (IRI) 標(biāo)識(shí)的 XML 元素和屬性集合,該集合通常稱作 XML“詞匯”,對(duì)XML Namespace 命名空間相關(guān)知識(shí)感興趣的朋友一起看看吧
    2021-08-08
  • MyBatis-Plus 自定義sql語句的實(shí)現(xiàn)

    MyBatis-Plus 自定義sql語句的實(shí)現(xiàn)

    這篇文章主要介紹了MyBatis-Plus 自定義sql語句的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評(píng)論

沙田区| 徐闻县| 景东| 英山县| 苏尼特左旗| 临桂县| 龙海市| 称多县| 霍山县| 甘洛县| 耿马| 迁安市| 衡山县| 麦盖提县| 黄平县| 怀集县| 晋江市| 株洲市| 浙江省| 冀州市| 湘乡市| 安庆市| 安平县| 开远市| 普安县| 万载县| 邹城市| 南昌市| 石林| 岳普湖县| 彩票| 泸溪县| 布尔津县| 内丘县| 牟定县| 巨野县| 香港 | 尖扎县| 阿拉善左旗| 广元市| 四平市|