欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的BigDecimal使用問(wèn)題小結(jié)

 更新時(shí)間:2025年04月28日 10:01:37   作者:碼熔burning  
BigDecimal 是 Java 中用于進(jìn)行精確十進(jìn)制計(jì)算的重要類, 它適用于金融、科學(xué)等需要高精度計(jì)算的場(chǎng)景,這篇文章讓我來(lái)詳細(xì)講解 Java 中的 BigDecimal 類,包括它的用途、適用場(chǎng)景、以及潛在問(wèn)題,感興趣的朋友一起看看吧

這篇文章讓我來(lái)詳細(xì)講解 Java 中的 BigDecimal 類,包括它的用途、適用場(chǎng)景、以及潛在問(wèn)題。

一、 BigDecimal 是什么?

BigDecimal 是 Java 中用于表示任意精度的十進(jìn)制數(shù)的類。它解決了 floatdouble 在進(jìn)行精確計(jì)算時(shí)可能出現(xiàn)的精度丟失問(wèn)題。BigDecimal 類提供了對(duì)數(shù)字進(jìn)行加、減、乘、除等運(yùn)算的方法,并且可以控制舍入模式。

二、 為什么需要 BigDecimal?

floatdouble 類型是基于二進(jìn)制的浮點(diǎn)數(shù)表示,它們無(wú)法精確地表示某些十進(jìn)制數(shù)(例如 0.1)。這會(huì)導(dǎo)致在進(jìn)行涉及貨幣、金融等需要精確計(jì)算的場(chǎng)景時(shí)出現(xiàn)誤差。 

例如:

double a = 0.1;
double b = 0.2;
double sum = a + b;
System.out.println(sum); // 輸出:0.30000000000000004 ??

可以看到,0.1 + 0.2 的結(jié)果并不是精確的 0.3。 而BigDecimal 可以避免這種問(wèn)題。?

三、 BigDecimal 的使用場(chǎng)景

  • 金融計(jì)算: 貨幣計(jì)算、利率計(jì)算、稅收計(jì)算等,任何需要精確到小數(shù)點(diǎn)后幾位的計(jì)算。
  • ??科學(xué)計(jì)算: 需要高精度計(jì)算的科學(xué)領(lǐng)域,例如物理、化學(xué)等。
  • ??商業(yè)應(yīng)用: 訂單金額計(jì)算、庫(kù)存管理、報(bào)表生成等。
  • ??任何需要避免浮點(diǎn)數(shù)精度問(wèn)題的場(chǎng)景。 ??

BigDecimal 的用法

創(chuàng)建 BigDecimal 對(duì)象:

  • BigDecimal(String val):推薦使用字符串構(gòu)造方法,避免 double 帶來(lái)的精度問(wèn)題。 ??
  • BigDecimal(int val)
  • BigDecimal(long val)
  • BigDecimal(double val):不推薦,因?yàn)?double 本身就可能存在精度問(wèn)題。 ??
  • BigDecimal.valueOf(double val):底層也是將 double 轉(zhuǎn)換為字符串,然后創(chuàng)建 BigDecimal 對(duì)象,比直接使用 BigDecimal(double) 更好。 ??
  • BigDecimal num1 = new BigDecimal("0.1"); // 推薦
  • BigDecimal num2 = new BigDecimal(0.1);   // 不推薦
  • BigDecimal num3 = BigDecimal.valueOf(0.1); // 推薦
BigDecimal num1 = new BigDecimal("0.1"); // 推薦
BigDecimal num2 = new BigDecimal(0.1);   // 不推薦
BigDecimal num3 = BigDecimal.valueOf(0.1); // 推薦

常用方法:

  • add(BigDecimal augend):加法
  • subtract(BigDecimal subtrahend):減法
  • multiply(BigDecimal multiplicand):乘法
  • divide(BigDecimal divisor):除法
  • divide(BigDecimal divisor, int scale, RoundingMode roundingMode):除法,指定精度和舍入模式。
  • setScale(int newScale, RoundingMode roundingMode):設(shè)置精度和舍入模式。
  • compareTo(BigDecimal val):比較大?。ǚ祷?-1, 0, 1,分別表示小于、等于、大于)
  • toString():轉(zhuǎn)換為字符串
  • intValue(), longValue(), floatValue(), doubleValue():轉(zhuǎn)換為基本數(shù)據(jù)類型(可能丟失精度) ??

舍入模式(RoundingMode):

  • RoundingMode.UP:遠(yuǎn)離零方向舍入。
  • RoundingMode.DOWN:趨向零方向舍入。
  • RoundingMode.CEILING:趨向正無(wú)窮方向舍入。
  • RoundingMode.FLOOR:趨向負(fù)無(wú)窮方向舍入。
  • RoundingMode.HALF_UP:四舍五入(大于等于 0.5 進(jìn)位)。
  • RoundingMode.HALF_DOWN:五舍六入(大于 0.5 進(jìn)位)。
  • RoundingMode.HALF_EVEN:銀行家舍入法(四舍六入,五看前一位,偶數(shù)舍去,奇數(shù)進(jìn)位)。
  • RoundingMode.UNNECESSARY:斷言不需要舍入,如果需要舍入則拋出 ArithmeticException。

示例代碼

import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalExample {
    public static void main(String[] args) {
        BigDecimal num1 = new BigDecimal("10.5");
        BigDecimal num2 = new BigDecimal("3.2");
        // 加法
        BigDecimal sum = num1.add(num2);
        System.out.println("Sum: " + sum);
        // 減法
        BigDecimal difference = num1.subtract(num2);
        System.out.println("Difference: " + difference);
        // 乘法
        BigDecimal product = num1.multiply(num2);
        System.out.println("Product: " + product);
        // 除法 (需要指定精度和舍入模式)
        try {
            BigDecimal quotient = num1.divide(num2, 2, RoundingMode.HALF_UP); // 保留兩位小數(shù),四舍五入
            System.out.println("Quotient: " + quotient);
        } catch (ArithmeticException e) {
            System.out.println("除法運(yùn)算出錯(cuò):" + e.getMessage());
        }
        // 設(shè)置精度
        BigDecimal scaledNum = num1.setScale(1, RoundingMode.HALF_UP); // 保留一位小數(shù),四舍五入
        System.out.println("Scaled Number: " + scaledNum);
        // 比較大小
        int comparisonResult = num1.compareTo(num2);
        if (comparisonResult > 0) {
            System.out.println("num1 is greater than num2");
        } else if (comparisonResult < 0) {
            System.out.println("num1 is less than num2");
        } else {
            System.out.println("num1 is equal to num2");
        }
    }
}

四、 BigDecimal 的潛在問(wèn)題和注意事項(xiàng)

  • 性能問(wèn)題: BigDecimal 的運(yùn)算比 floatdouble 慢得多。 ?? 因?yàn)樗枰M(jìn)行復(fù)雜的計(jì)算來(lái)保證精度。 因此,只有在需要精確計(jì)算的場(chǎng)景下才應(yīng)該使用 BigDecimal
  • 不可變性: BigDecimal 對(duì)象是不可變的。 這意味著每次運(yùn)算都會(huì)創(chuàng)建一個(gè)新的 BigDecimal 對(duì)象。 因此,在循環(huán)中進(jìn)行大量的 BigDecimal 運(yùn)算可能會(huì)導(dǎo)致性能問(wèn)題和內(nèi)存占用過(guò)高。 ??
BigDecimal total = BigDecimal.ZERO;
for (int i = 0; i < 1000; i++) {
    total = total.add(new BigDecimal("0.1")); // 每次循環(huán)都創(chuàng)建新的 BigDecimal 對(duì)象
}
System.out.println(total);

如果需要進(jìn)行大量的 BigDecimal 運(yùn)算,可以考慮使用 BigDecimalMathContext 來(lái)控制精度和舍入模式,或者使用其他優(yōu)化技巧。

  • NullPointerExceptionBigDecimal 對(duì)象可以為 null。 在使用 BigDecimal 對(duì)象之前,應(yīng)該先進(jìn)行判空檢查,避免 NullPointerException。 ??
  • 除法運(yùn)算: 在進(jìn)行除法運(yùn)算時(shí),必須指定精度和舍入模式,否則可能會(huì)拋出 ArithmeticException(如果結(jié)果是無(wú)限循環(huán)小數(shù))。 ?
  • 構(gòu)造方法選擇: 始終使用 BigDecimal(String)BigDecimal.valueOf(double) 構(gòu)造方法,避免 double 帶來(lái)的精度問(wèn)題。 ??
  • 比較大小: 使用 compareTo() 方法進(jìn)行比較,不要使用 ==。 == 比較的是對(duì)象的引用,而不是值。 ??
  • 緩存 BigDecimal 對(duì)象: 對(duì)于一些常用的 BigDecimal 值(例如 0, 1, 10),可以考慮使用靜態(tài)常量來(lái)緩存這些對(duì)象,避免重復(fù)創(chuàng)建。 ??
public static final BigDecimal ZERO = BigDecimal.valueOf(0);
public static final BigDecimal ONE = BigDecimal.valueOf(1);
public static final BigDecimal TEN = BigDecimal.valueOf(10);

五、 總結(jié)

BigDecimal 是 Java 中用于進(jìn)行精確十進(jìn)制計(jì)算的重要類。 它適用于金融、科學(xué)等需要高精度計(jì)算的場(chǎng)景。 但是,BigDecimal 的運(yùn)算速度較慢,并且需要注意一些潛在的問(wèn)題,例如精度、舍入模式、NullPointerException 等。 在選擇使用 BigDecimal 時(shí),需要權(quán)衡精度和性能,并根據(jù)實(shí)際情況選擇合適的構(gòu)造方法、運(yùn)算方法和舍入模式。 ??

希望這篇文章能夠幫助你更好地理解和使用 BigDecimal 類。 ??

到此這篇關(guān)于Java中的BigDecimal使用問(wèn)題小結(jié)的文章就介紹到這了,更多相關(guān)Java BigDecimal內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式

    SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式

    這篇文章主要介紹了SpringBoot中處理的轉(zhuǎn)發(fā)與重定向方式,分別就轉(zhuǎn)發(fā)和重定向做了概念解說(shuō),結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-11-11
  • 詳解Java基礎(chǔ)篇--面向?qū)ο?(構(gòu)造方法,static、this關(guān)鍵字)

    詳解Java基礎(chǔ)篇--面向?qū)ο?(構(gòu)造方法,static、this關(guān)鍵字)

    這篇文章主要介紹了Java基礎(chǔ)篇--面向?qū)ο?(構(gòu)造方法,static、this關(guān)鍵字),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 解決SpringCloud下spring-boot-maven-plugin插件的打包問(wèn)題

    解決SpringCloud下spring-boot-maven-plugin插件的打包問(wèn)題

    這篇文章主要介紹了SpringCloud下spring-boot-maven-plugin插件的打包問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • java中線程池最實(shí)用的創(chuàng)建與關(guān)閉指南

    java中線程池最實(shí)用的創(chuàng)建與關(guān)閉指南

    試中經(jīng)常會(huì)問(wèn)到,創(chuàng)建一個(gè)線程池需要哪些參數(shù)啊,線程池的工作原理啊,卻很少會(huì)問(wèn)到線程池如何安全關(guān)閉的,下面這篇文章主要給大家介紹了關(guān)于java中線程池最實(shí)用的創(chuàng)建與關(guān)閉的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • Java Iterator迭代器與foreach循環(huán)代碼解析

    Java Iterator迭代器與foreach循環(huán)代碼解析

    這篇文章主要介紹了Java-Iterator迭代器與foreach循環(huán),主要包括Iterator迭代器接口的操作方法和foreach 循環(huán)語(yǔ)法解析,需要的朋友可以參考下
    2022-04-04
  • Java foreach相關(guān)原理及用法解析

    Java foreach相關(guān)原理及用法解析

    這篇文章主要介紹了Java foreach相關(guān)原理及用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java自動(dòng)拆箱空指針異常的解決

    Java自動(dòng)拆箱空指針異常的解決

    這篇文章主要介紹了Java自動(dòng)拆箱空指針異常的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • mysql數(shù)據(jù)庫(kù)忘記密碼時(shí)如何修改

    mysql數(shù)據(jù)庫(kù)忘記密碼時(shí)如何修改

    本文主要介紹了mysql數(shù)據(jù)庫(kù)忘記密碼時(shí)如何修改的步驟方法,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • 出現(xiàn)SLF4J:?Failed?to?load?class?“org.slf4j.impl.StaticLoggerBinder“.的解決方法

    出現(xiàn)SLF4J:?Failed?to?load?class?“org.slf4j.impl.StaticLog

    本文主要介紹了出現(xiàn)SLF4J:?Failed?to?load?class?“org.slf4j.impl.StaticLoggerBinder“.的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • SpringBoot淺析緩存機(jī)制之Redis單機(jī)緩存應(yīng)用

    SpringBoot淺析緩存機(jī)制之Redis單機(jī)緩存應(yīng)用

    在上文中我介紹了Spring Boot使用EhCache 2.x來(lái)作為緩存的實(shí)現(xiàn),本文接著介紹使用單機(jī)版的Redis作為緩存的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評(píng)論