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

BigDecimal用錯了,哭暈在廁所......

開發 前端
理論上,它比 double 或 float 更精確,但如果你用得不對,精度丟失的問題會讓你哭暈在廁所。今天我們就來聊聊 ,錯誤使用BigDecimal的6種場景,為什么會發生問題,以及怎么避免問題,希望對你會有所幫助。

前言

在日常開發中,很多小伙伴喜歡用 BigDecimal 來處理精確計算,比如錢、分數、比例啥的。

理論上,它比 double 或 float 更精確,但如果你用得不對,精度丟失的問題會讓你哭暈在廁所。

今天我們就來聊聊 ,錯誤使用BigDecimal的6種場景,為什么會發生問題,以及怎么避免問題,希望對你會有所幫助。

1.直接用浮點數初始化

不少小伙伴習慣這樣寫:

BigDecimal num = new BigDecimal(0.1);
System.out.println(num);

打印結果:0.1000000000000000055511151231257827021181583404541015625

并非打印的:0.1

問題出在哪?

這不是 BigDecimal 的問題,而是浮點數本身的“鍋”。

在Java中,double的精度有限的,0.1 轉換成二進制是個無限循環小數,直接傳進去會帶上誤差。

正確姿勢是傳字符串:

BigDecimal num = new BigDecimal("0.1");
System.out.println(num);

打印結果:0.1,是正確的。

注意:永遠不要用 BigDecimal(double) 構造函數,用字符串或整數更靠譜。也可以使用BigDecimal.valueOf()函數。

2.加減乘除時不設精度

有些小伙伴做加減乘除的時候,直接寫:

BigDecimal a = new BigDecimal("1.03");
BigDecimal b = new BigDecimal("0.42");
//減法
BigDecimal result = a.subtract(b);
System.out.println(result);

打印結果::0.61,沒問題。

但問題在 除法 時:

BigDecimal c = new BigDecimal("10");
BigDecimal d = new BigDecimal("3");
BigDecimal result = c.divide(d);

運行直接炸了:java.lang.ArithmeticException: Non-terminating decimal expansion

報錯的根本原因:10/3 是無限小數,BigDecimal 默認不保留小數點后面,精度溢出。

那么,我們要如何優化呢?

答:加一個 MathContext 或指定精度。

例如:

BigDecimal result = c.divide(d, 2, RoundingMode.HALF_UP);
System.out.println(result);

打印結果:3.33,可以正常運行。

因此,我們需要注意,在BigDecimal 做除法時 ,必須指定精度。

3.用 equals 判斷相等

BigDecimal 的 equals 會比較 值和精度,這坑了不少人:

BigDecimal x = new BigDecimal("1.0");
BigDecimal y = new BigDecimal("1.00");

System.out.println(x.equals(y));

打印結果:false。

盡管 1.0 和 1.00 的數值相等,但精度不一樣,equals 判定為不同。

優化方法,用 compareTo 比較數值:

例如:

System.out.println(x.compareTo(y) == 0);

打印結果:true

需要特別注意的地方是:我們在判斷兩個BigDecimal對象是否相等時,應該用 compareTo方法,別用 equals方法。

4.使用 scale 時忽視實際含義

有些小伙伴搞不清 scale(小數位數)和 precision(總位數)的區別,直接寫:

BigDecimal num = new BigDecimal("123.4500");
System.out.println(num.scale());

打印結果:4

但如果你寫成下面這樣的:

BigDecimal stripped = num.stripTrailingZeros();
System.out.println(stripped.scale());

打印結果卻是:1

scale 會發生變化,搞不好會影響后續計算。

那么,我們要如何優化方法呢?

答:明確 scale 的含義。

如果要固定小數位,使用 setScale:

BigDecimal fixed = num.setScale(2, RoundingMode.HALF_UP);
System.out.println(fixed);

打印結果:123.45。

我們不要混淆 scale 和 precision,必要時顯式設置小數位數。

5.忽略不可變性

BigDecimal 是不可變的,但有些小伙伴會這樣寫:

BigDecimal sum = new BigDecimal("0");
for (int i = 0; i < 5; i++) {
    sum.add(new BigDecimal("1"));
}

打印結果:0

問題原因是 add 方法不會改變原對象,而是返回一個新的 BigDecimal 實例。

那么,我們要如何優化呢?

答:用變量接住返回值。

BigDecimal sum = new BigDecimal("0");
for (int i = 0; i < 5; i++) {
    sum = sum.add(new BigDecimal("1"));
}
System.out.println(sum);

打印結果是:5

BigDecimal 操作后需要接住新實例。

6.忽視性能問題

BigDecimal 是很精確,但也很慢。

如果大量計算時用 BigDecimal,會拖累性能,比如計算利息:

BigDecimal principal = new BigDecimal("10000");
BigDecimal rate = new BigDecimal("0.05");
BigDecimal interest = principal.multiply(rate);

一個循環里搞上百萬次,性能直接拉垮。

那么,這種情況我們又該如何優化呢?

答:能用整數就用整數(比如分代替元)。

批量計算時,用 double 計算,結果最后轉換成 BigDecimal。

double principal = 10000;
double rate = 0.05;
BigDecimal interest = BigDecimal.valueOf(principal * rate);
System.out.println(interest);

打印結果:500.00

參與大批量計算時,兩個BigDecimal對象直接計算會比較慢,盡量少用,能優化的地方別放過。

寫在最后

BigDecimal 是個非常強大的數字類工具,但也是個“細節狂魔”。

只有用對了,你才能真正享受它帶來的好處,否則就是自找麻煩。

希望這篇文章能幫到你,不要再踩坑。


責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2014-10-17 10:31:25

2015-05-14 14:24:27

互聯網IT從業者

2017-08-15 10:20:08

Surface微軟消費者

2024-12-23 08:19:19

2016-12-02 13:01:54

Android 7.1安卓

2022-04-26 09:53:30

WiFi網絡

2021-12-15 10:20:08

緩存架構開發

2024-12-27 09:29:09

2024-06-27 08:36:12

Lodash對象類型isObject?

2018-01-09 20:53:13

2024-09-09 11:11:45

2015-07-17 15:23:52

中國網

2015-10-28 17:35:51

資本

2025-06-18 03:30:00

AI人工智能智能體

2014-12-15 15:33:25

Google測試馬桶

2024-10-14 13:12:59

2014-09-09 10:17:28

WiFi

2017-09-15 11:53:48

廁所物聯網虹橋站

2011-07-13 09:21:59

2010-04-22 10:12:01

Oracle收購SUN
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区二区日韩 | 日韩中文字幕一区二区 | 99re在线视频 | 国产高清视频在线观看 | 国产a一区二区 | 国产精品三级久久久久久电影 | 欧美精品在欧美一区二区 | 欧美精品在线观看 | 97精品国产97久久久久久免费 | 欧美精品一区二区三区在线 | 亚洲区一区二区 | 国产99久久久国产精品下药 | 国产精品无码久久久久 | 在线播放中文字幕 | 国产精品久久久亚洲 | 中文字幕第十五页 | 日韩a在线 | 天天激情综合 | 日韩精品视频一区二区三区 | 亚洲视频在线看 | 日韩中文字幕区 | 在线看一区二区 | 国产精品永久久久久久久www | 亚洲精品一二三 | 精品国产一区二区久久 | 精品国产乱码久久久久久老虎 | 午夜在线 | 高清国产午夜精品久久久久久 | 91久久精品一区二区二区 | 中文字幕不卡在线88 | 91aiai | 欧美成人专区 | 好姑娘高清在线观看电影 | 日韩精品一区二区三区在线播放 | 中文字幕精品一区二区三区精品 | 成人精品免费视频 | 国产精品久久久久久二区 | 欧美日韩中文字幕在线播放 | 人人干视频在线 | 欧美中文一区 | 成人影视网址 |