成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

踩坑日記:BigDecimal四大坑,真的會用BigDecimal?

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

一、前言

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

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

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

今天就總結一下BigDecimal使用時需要注意的點!

二、BigDecimal在理解

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

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

BigDecimal在金融領域、貨幣計算、稅務計算、精確計算需求以及其他需要保持精度和執(zhí)行準確計算的場景中廣泛應用。

「當然要注意」:

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

由于BigDecimal是一個對象,并且執(zhí)行計算時需要更多的內存和處理時間,與使用原生數據類型相比,它可能會稍微降低性能。因此,在大量計算或對性能要求較高的情況下,需要權衡使用BigDecimal的優(yōu)勢和劣勢。

三、BigDecimal注意點

1、BigDecimal使用equals

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

當然也不用使用 == != 來比較哈!!

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

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內部到底是怎么比較的:

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

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

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

我們打斷點可以看到一個是3位精度,一個0位!

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

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

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

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

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

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

源碼:

@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方法實現了Comparable接口,準備的比較的兩者! 有興趣可以debug看看compareTo方法!這里就不給大家展示了!!

2、BigDecimal初始化

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

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

BigDecimal bigDecimal2 = new BigDecimal("0.11");

BigDecimal bigDecimal = new BigDecimal(0.11);

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

3、BigDecimal精度問題

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

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

BigDecimal bigDecimal2 = new BigDecimal("10");

BigDecimal bigDecimal = new BigDecimal("3");

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

4、BigDecimal多余0

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

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

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

四、總結

我們來在總結有哪些注意事項哈:

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

大家一定注意這些東西,特別是設計到錢的計算,一個不小心一個小目標沒了!

責任編輯:姜華 來源: 小王博客基地
相關推薦

2024-05-30 12:15:04

2024-04-10 08:39:56

BigDecimal浮點數二進制

2022-06-06 00:25:09

Golangpanic死鎖

2020-06-04 14:15:55

Java中BigDecimal函數

2022-07-19 07:30:06

BigDecimal運算float

2022-12-08 09:34:26

開發(fā)操作

2022-12-23 08:37:16

BigDecimaljava

2018-07-06 05:05:07

2025-04-29 10:00:15

NVRIPC弱電

2018-04-02 07:32:15

2023-02-17 08:20:24

SQL腳本數據庫

2023-01-18 23:20:25

編程開發(fā)

2020-09-15 08:46:26

Kubernetes探針服務端

2020-09-06 10:02:32

項目管理戰(zhàn)略目標CIO

2021-09-03 11:15:18

場景sql配置

2021-09-26 09:16:45

RedisGeo 類型數據類型

2019-08-07 06:16:28

物聯(lián)網IOT技術

2021-05-10 11:55:57

ThreadLocal內存Java

2023-02-20 08:11:04

2021-10-28 19:10:02

Go語言編碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久久黄 | 欧美一区二区三区在线观看视频 | 在线a视频网站 | 国产精品视频yy9299一区 | 国产一级片免费看 | 日韩成年人视频在线 | 日韩欧美在线不卡 | 成人毛片一区二区三区 | 国产高清视频在线 | www.日本在线播放 | 亚洲一区二区在线播放 | 欧美三级免费观看 | www.日本三级| 在线国产精品一区 | 日韩在线视频一区二区三区 | 日本h片在线观看 | 免费看一区二区三区 | 免费观看a级毛片在线播放 黄网站免费入口 | 三级视频在线观看电影 | 综合自拍 | 欧美精品v | 一区中文字幕 | 99九色| 日日干天天操 | 8x国产精品视频一区二区 | 999re5这里只有精品 | 中文字幕乱码一区二区三区 | 久草免费在线视频 | 中文字幕亚洲视频 | 日本涩涩网| 色婷婷久久久亚洲一区二区三区 | 欧美日韩久久精品 | 日韩免费高清视频 | 亚洲欧美中文日韩在线v日本 | 亚洲一二三区在线观看 | 人人做人人澡人人爽欧美 | 国产一级一级国产 | 成人综合视频在线观看 | 成人一级毛片 | 日本偷偷操| 日韩欧美不卡 |