Java之BigDecimal詳解

阿杰同學發表於2020-12-19

一、BigDecimal概述
​ Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變數double可以處理16位有效數,但在實際應用中,可能需要對更大或者更小的數進行運算和處理。一般情況下,對於那些不需要準確計算精度的數字,我們可以直接使用Float和Double處理,但是Double.valueOf(String) 和Float.valueOf(String)會丟失精度。所以開發中,如果我們需要精確計算的結果,則必須使用BigDecimal類來操作。

​ BigDecimal所建立的是物件,故我們不能使用傳統的+、-、*、/等算術運算子直接對其物件進行數學運算,而必須呼叫其相對應的方法。方法中的引數也必須是BigDecimal的物件。構造器是類的特殊方法,專門用來建立物件,特別是帶有引數的物件。

二、BigDecimal常用建構函式
2.1、常用建構函式
BigDecimal(int)

建立一個具有引數所指定整數值的物件

BigDecimal(double)

建立一個具有引數所指定雙精度值的物件

BigDecimal(long)

建立一個具有引數所指定長整數值的物件

BigDecimal(String)

建立一個具有引數所指定以字串表示的數值的物件


BigDecimal 工具類

import java.math.BigDecimal;

/**

  • 用於高精確處理常用的數學運算
    */
    public class ArithmeticUtils {
    //預設除法運算精度
    private static final int DEF_DIV_SCALE = 10;

    /**

    • 提供精確的加法運算
    • @param v1 被加數
    • @param v2 加數
    • @return 兩個引數的和
      */

    public static double add(double v1, double v2) {
    BigDecimal b1 = new BigDecimal(Double.toString(v1));
    BigDecimal b2 = new BigDecimal(Double.toString(v2));
    return b1.add(b2).doubleValue();
    }

    /**

    • 提供精確的加法運算
    • @param v1 被加數
    • @param v2 加數
    • @return 兩個引數的和
      */
      public static BigDecimal add(String v1, String v2) {
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v2);
      return b1.add(b2);
      }

    /**

    • 提供精確的加法運算
    • @param v1 被加數
    • @param v2 加數
    • @param scale 保留scale 位小數
    • @return 兩個引數的和
      */
      public static String add(String v1, String v2, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(
      “The scale must be a positive integer or zero”);
      }
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v2);
      return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
      }

    /**

    • 提供精確的減法運算
    • @param v1 被減數
    • @param v2 減數
    • @return 兩個引數的差
      */
      public static double sub(double v1, double v2) {
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.subtract(b2).doubleValue();
      }

    /**

    • 提供精確的減法運算。
    • @param v1 被減數
    • @param v2 減數
    • @return 兩個引數的差
      */
      public static BigDecimal sub(String v1, String v2) {
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v2);
      return b1.subtract(b2);
      }

    /**

    • 提供精確的減法運算
    • @param v1 被減數
    • @param v2 減數
    • @param scale 保留scale 位小數
    • @return 兩個引數的差
      */
      public static String sub(String v1, String v2, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(
      “The scale must be a positive integer or zero”);
      }
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v2);
      return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
      }

    /**

    • 提供精確的乘法運算
    • @param v1 被乘數
    • @param v2 乘數
    • @return 兩個引數的積
      */
      public static double mul(double v1, double v2) {
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.multiply(b2).doubleValue();
      }

    /**

    • 提供精確的乘法運算
    • @param v1 被乘數
    • @param v2 乘數
    • @return 兩個引數的積
      */
      public static BigDecimal mul(String v1, String v2) {
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v2);
      return b1.multiply(b2);
      }

    /**

    • 提供精確的乘法運算
    • @param v1 被乘數
    • @param v2 乘數
    • @param scale 保留scale 位小數
    • @return 兩個引數的積
      */
      public static double mul(double v1, double v2, int scale) {
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return round(b1.multiply(b2).doubleValue(), scale);
      }

    /**

    • 提供精確的乘法運算
    • @param v1 被乘數
    • @param v2 乘數
    • @param scale 保留scale 位小數
    • @return 兩個引數的積
      */
      public static String mul(String v1, String v2, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(
      “The scale must be a positive integer or zero”);
      }
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v2);
      return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
      }

    /**

    • 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到
    • 小數點以後10位,以後的數字四捨五入
    • @param v1 被除數
    • @param v2 除數
    • @return 兩個引數的商
      */

    public static double div(double v1, double v2) {
    return div(v1, v2, DEF_DIV_SCALE);
    }

    /**

    • 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale引數指
    • 定精度,以後的數字四捨五入
    • @param v1 被除數
    • @param v2 除數
    • @param scale 表示表示需要精確到小數點以後幾位。
    • @return 兩個引數的商
      */
      public static double div(double v1, double v2, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(“The scale must be a positive integer or zero”);
      }
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
      }

    /**

    • 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale引數指
    • 定精度,以後的數字四捨五入
    • @param v1 被除數
    • @param v2 除數
    • @param scale 表示需要精確到小數點以後幾位
    • @return 兩個引數的商
      */
      public static String div(String v1, String v2, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(“The scale must be a positive integer or zero”);
      }
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v1);
      return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
      }

    /**

    • 提供精確的小數位四捨五入處理
    • @param v 需要四捨五入的數字
    • @param scale 小數點後保留幾位
    • @return 四捨五入後的結果
      */
      public static double round(double v, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(“The scale must be a positive integer or zero”);
      }
      BigDecimal b = new BigDecimal(Double.toString(v));
      return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
      }

    /**

    • 提供精確的小數位四捨五入處理
    • @param v 需要四捨五入的數字
    • @param scale 小數點後保留幾位
    • @return 四捨五入後的結果
      */
      public static String round(String v, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(
      “The scale must be a positive integer or zero”);
      }
      BigDecimal b = new BigDecimal(v);
      return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
      }

    /**

    • 取餘數
    • @param v1 被除數
    • @param v2 除數
    • @param scale 小數點後保留幾位
    • @return 餘數
      */
      public static String remainder(String v1, String v2, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(
      “The scale must be a positive integer or zero”);
      }
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v2);
      return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
      }

    /**

    • 取餘數 BigDecimal
    • @param v1 被除數
    • @param v2 除數
    • @param scale 小數點後保留幾位
    • @return 餘數
      */
      public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {
      if (scale < 0) {
      throw new IllegalArgumentException(
      “The scale must be a positive integer or zero”);
      }
      return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
      }

    /**

    • 比較大小
    • @param v1 被比較數
    • @param v2 比較數
    • @return 如果v1 大於v2 則 返回true 否則false
      */
      public static boolean compare(String v1, String v2) {
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(v2);
      int bj = b1.compareTo(b2);
      boolean res;
      if (bj > 0)
      res = true;
      else
      res = false;
      return res;
      }
      }

相關文章