偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

又踩坑了!BigDecimal使用的五個(gè)坑!

大數(shù)據(jù) 數(shù)據(jù)分析
由于計(jì)算機(jī)的資源是有限的,所以是沒辦法用二進(jìn)制精確的表示 0.1,只能用「近似值」來表示,就是在有限的精度情況下,最大化接近 0.1 的二進(jìn)制數(shù),于是就會造成精度缺失的情況。

前言

大家好,我是田螺。

在日常開發(fā)中,BigDecimal類被廣泛用于精確的數(shù)值、金額的計(jì)算。但是在使用BigDecimal的過程中,存在以下這幾個(gè)坑,大家要注意一下哈~~

1.浮點(diǎn)數(shù)初始化的坑

反例:

BigDecimal problematic = new BigDecimal(0.1);
System.out.println("Problematic: " + problematic.toString()); 
//輸出 Problematic: 0.1000000000000000055511151231257827021181583404541015625

可以發(fā)現(xiàn),直接使用new BigDecimal(double)構(gòu)造方法可能會得到一個(gè)看起來相當(dāng)奇怪的結(jié)果。這是因?yàn)閐ouble本身的精度問題會被帶入BigDecimal中。為了避免這個(gè)問題,推薦使用String參數(shù)的構(gòu)造方法或者使用BigDecimal.valueOf方法,例如new BigDecimal("0.1"),這樣可以確保BigDecimal的精度。

由于計(jì)算機(jī)的資源是有限的,所以是沒辦法用二進(jìn)制精確的表示 0.1,只能用「近似值」來表示,就是在有限的精度情況下,最大化接近 0.1 的二進(jìn)制數(shù),于是就會造成精度缺失的情況。

正例:

BigDecimal problematic1 =  BigDecimal.valueOf(0.1);
System.out.println("Problematic: " + problematic1.toString());

BigDecimal problematic2 =  new BigDecimal("0.1");
System.out.println("Problematic: " + problematic2.toString());
//輸出
Problematic: 0.1
Problematic: 0.1

2. 比較數(shù)值時(shí)使用compareTo()方法而非equals()

BigDecimal bd1 = new BigDecimal("0.10");
BigDecimal bd2 = new BigDecimal("0.1");
System.out.println(bd1.equals(bd2)); // 輸出: false
System.out.println(bd1.compareTo(bd2) == 0); // 輸出: true

BigDecimal的equals方法不僅比較數(shù)值,還會比較對象的scale(小數(shù)點(diǎn)后的位數(shù)),如果只想比較數(shù)值,而不考慮scale,應(yīng)該使用compareTo方法。

圖片圖片

3.做除法時(shí),未指定精度可能異常

BigDecimal dividend = new BigDecimal("10");
BigDecimal divisor = new BigDecimal("3");
BigDecimal result = dividend.divide(divisor); // 未指定精度和舍入模式
System.out.println(result);
//輸出
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
 at java.math.BigDecimal.divide(BigDecimal.java:1693)
 at com.example.demo.controller.Test.main(Test.java:26)

除法操作將10除以3,結(jié)果是無限循環(huán)小數(shù)3.3333...,但由于未指定精度和舍入模式,會拋出ArithmeticException異常。

官方有給出解釋:

"If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown. Otherwise, the exact result of the division is returned, as done for other operations."

要使用BigDecimal時(shí),要記得指定精度,避免因?yàn)榫葐栴}帶來的損失。

4. BigDecimal轉(zhuǎn)String,科學(xué)計(jì)數(shù)法展示問題

System.out.println( new BigDecimal("0.0000000000001").toString());
BigDecimal bigDecimal = new BigDecimal("1E+12");
System.out.println(bigDecimal.toString());
//輸出 1E-13
//輸出 1E+12

這是因?yàn)?nbsp;toString() 某些場景下使用科學(xué)計(jì)數(shù)法展示。如果不想用任何計(jì)數(shù)法,可以使用 toPlainString()

System.out.println( new BigDecimal("0.0000000000001").toPlainString());
BigDecimal bigDecimal = new BigDecimal("1E+12");
System.out.println(bigDecimal.toPlainString());
//輸出 
0.0000000000001
1000000000000

5. 注意使用setScale方法設(shè)置精度

BigDecimal number = new BigDecimal("123.4567");
BigDecimal roundedNumber = number.setScale(2, RoundingMode.HALF_UP);
//輸出
123.46

因?yàn)锽igDecimal的精度是無限的,因此一般在計(jì)算的時(shí)候,要注意設(shè)置精度幾位。

并且,RoundingMode.HALF_UP 是一種舍入模式,用于四舍五入,即當(dāng)數(shù)字的一部分被舍去時(shí),如果剩余部分大于或等于0.5,則向上舍入。除了HALF_UP之外,還有幾個(gè)常用的舍入模式:

  • UP:遠(yuǎn)離零方向舍入的舍入模式??偸窃诜橇闵釛壊糠种霸黾訑?shù)字。
  • DOWN:接近零方向舍入的舍入模式??偸窃诜橇闵釛壊糠种皽p少數(shù)字。
  • CEILING:接近正無窮大的方向舍入的舍入模式。如果BigDecimal是正的,則舍入行為與UP相同;如果是負(fù)的,則舍入行為與DOWN相同。
  • FLOOR:接近負(fù)無窮大的方向舍入的舍入模式。如果BigDecimal是正的,則舍入行為與DOWN相同;如果是負(fù)的,則舍入行為與UP相同。
  • HALF_DOWN:向“最近鄰居”舍入,除非兩邊距離相等,此時(shí)向下舍入。
  • HALF_EVEN:向“最近鄰居”舍入,除非兩邊距離相等,此時(shí)向偶數(shù)舍入。這種模式也稱為“銀行家舍入法”,因?yàn)樗鼫p少了累計(jì)錯(cuò)誤。

還有一個(gè)點(diǎn),就是:使用setScale方法實(shí)際上會產(chǎn)生一個(gè)全新的BigDecimal實(shí)例,而不會更改原有對象。所以,當(dāng)你用setScale調(diào)整了數(shù)字精度后,別忘了把新生成的對象賦值回原來的變量。

責(zé)任編輯:武曉燕 來源: 撿田螺的小男孩
相關(guān)推薦

2022-11-18 07:34:12

Docker項(xiàng)目目錄

2024-02-04 08:26:38

線程池參數(shù)內(nèi)存

2023-03-06 07:50:19

內(nèi)存回收Go

2023-06-30 08:10:14

JavaBigDecimal

2024-11-20 18:16:39

MyBatis批量操作數(shù)據(jù)庫

2024-03-11 18:17:18

Python字符串分隔符

2021-09-09 18:12:22

內(nèi)存分段式網(wǎng)絡(luò)

2025-04-29 10:17:42

2022-12-23 08:37:16

BigDecimaljava

2024-05-06 00:00:00

緩存高并發(fā)數(shù)據(jù)

2017-07-17 15:46:20

Oracle并行機(jī)制

2025-06-26 02:44:00

.NET開發(fā)者LINQ

2024-11-26 08:20:53

程序數(shù)據(jù)歸檔庫

2020-09-29 07:57:48

設(shè)置HttpClientContent-Typ

2022-02-28 08:55:31

數(shù)據(jù)庫MySQL索引

2023-02-20 08:11:04

2023-01-18 23:20:25

編程開發(fā)

2015-03-24 16:29:55

默認(rèn)線程池java

2020-09-15 08:46:26

Kubernetes探針服務(wù)端

2020-09-06 10:02:32

項(xiàng)目管理戰(zhàn)略目標(biāo)CIO
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號