BigDecimal常用方法

一、介绍

  Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算.
  其中 BigInteger 类是针对大整数的处理类,而 BigDecimal 类则是针对大小数的处理类.

  BigDecimal 类的实现用到了 BigInteger类,不同的是 BigDecimal 加入了小数的概念.
  float和Double只能用来做科学计算或者是工程计算;在商业计算中,对数字精度要求较高,必须使用 BigInteger 类和 BigDecimal 类,它支持任何精度的定点数,可以用它来精确计算货币值.
  BigDecimal类创建的是对象,不能使用传统的+、-、*、/等算术运算符直接对其进行数学运算,而必须调用其对应的方法.方法的参数也必须是BigDecimal类型的对象.

二、常用构造方法

BigDecimal BigDecimal(String s); //常用,推荐使用
static BigDecimal valueOf(double d); //常用,推荐使用
BigDecimal BigDecimal(double d); //不允许使用

  说明:

  1. double 参数的构造方法,不允许使用,因为它不能精确的得到相应的值,值会变大;
  2. String 构造方法是完全可预知的: 写入 new BigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的0.1; 因此,通常建议优先使用 String 构造方法;
  3. 静态方法 valueOf(double val) 内部实现,仍是将 double 类型转为 String 类型; 这通常是将 double(或float)转化为 BigDecimal 的首选方法;

三、封装常用的方法工具

import java.math.BigDecimal;  
public class MathExtend  
{  
  //默认除法运算精度  
  private static final int DEFAULT_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 String add(String v1, String v2)  
  {  
      BigDecimal b1 = new BigDecimal(v1);  
      BigDecimal b2 = new BigDecimal(v2);  
      return b1.add(b2).toString();  
  }  
   
 /** 
  * 提供精确的减法运算。 
  * @param v1 
  * @param v2 
  * @return 两个参数的差 
  */  
  public static double subtract(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 String subtract(String v1, String v2)  
  {  
      BigDecimal b1 = new BigDecimal(v1);  
      BigDecimal b2 = new BigDecimal(v2);  
      return b1.subtract(b2).toString();  
  }  
   
   
  /** 
  * 提供精确的乘法运算。 
  * @param v1 
  * @param v2 
  * @return 两个参数的积 
  */  
  public static double multiply(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 String multiply(String v1, String v2)  
  {  
      BigDecimal b1 = new BigDecimal(v1);  
      BigDecimal b2 = new BigDecimal(v2);  
      return b1.multiply(b2).toString();  
  }  
   
  /** 
  * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 
  * 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN 
  * @param v1 
  * @param v2 
  * @return 两个参数的商 
  */  
  public static double divide(double v1, double v2)  
  {  
      return divide(v1, v2, DEFAULT_DIV_SCALE);  
  }  
   
  /** 
   * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 
   * 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN 
   * @param v1 
   * @param v2 
   * @param scale 表示需要精确到小数点以后几位。 
   * @return 两个参数的商 
   */  
  public static double divide(double v1,double v2, int scale)  
  {  
      return divide(v1, v2, scale, BigDecimal.ROUND_HALF_EVEN);  
  }  
   
  /** 
   * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 
   * 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式 
   * @param v1 
   * @param v2 
   * @param scale 表示需要精确到小数点以后几位 
   * @param round_mode 表示用户指定的舍入模式 
   * @return 两个参数的商 
   */  
  public static double divide(double v1,double v2,int scale, int round_mode){  
          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, round_mode).doubleValue();  
  }  
   
  /** 
   * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 
   * 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN 
   * @param v1 
   * @param v2 
   * @return 两个参数的商,以字符串格式返回 
   */  
  public static String divide(String v1, String v2)  
  {  
      return divide(v1, v2, DEFAULT_DIV_SCALE);  
  }  
   
  /** 
   * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 
   * 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN 
   * @param v1 
   * @param v2 
   * @param scale 表示需要精确到小数点以后几位 
   * @return 两个参数的商,以字符串格式返回 
   */  
  public static String divide(String v1, String v2, int scale)  
  {  
      return divide(v1, v2, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_EVEN);  
  }  
   
  /** 
   * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 
   * 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式 
   * @param v1 
   * @param v2 
   * @param scale 表示需要精确到小数点以后几位 
   * @param round_mode 表示用户指定的舍入模式 
   * @return 两个参数的商,以字符串格式返回 
   */  
  public static String divide(String v1, String v2, int scale, int round_mode)  
  {  
      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.divide(b2, scale, round_mode).toString();  
  }  
   
  /** 
   * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN 
   * @param v 需要四舍五入的数字 
   * @param scale 小数点后保留几位 
   * @return 四舍五入后的结果 
   */  
  public static double round(double v,int scale)  
  {  
      return round(v, scale, BigDecimal.ROUND_HALF_EVEN);  
  }  
  /** 
   * 提供精确的小数位四舍五入处理 
   * @param v 需要四舍五入的数字 
   * @param scale 小数点后保留几位 
   * @param round_mode 指定的舍入模式 
   * @return 四舍五入后的结果 
   */  
  public static double round(double v, int scale, int round_mode)  
  {  
     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, round_mode).doubleValue();  
  }  
   
  /** 
   * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN 
   * @param v 需要四舍五入的数字 
   * @param scale 小数点后保留几位 
   * @return 四舍五入后的结果,以字符串格式返回 
   */  
  public static String round(String v, int scale)  
  {  
    return round(v, scale, BigDecimal.ROUND_HALF_EVEN);  
  }  
  /** 
   * 提供精确的小数位四舍五入处理 
   * @param v 需要四舍五入的数字 
   * @param scale 小数点后保留几位 
   * @param round_mode 指定的舍入模式 
   * @return 四舍五入后的结果,以字符串格式返回 
   */  
  public static String round(String v, int scale, int round_mode)  
  {  
     if(scale<0)  
     {  
         throw new IllegalArgumentException("The scale must be a positive integer or zero");  
     }  
     BigDecimal b = new BigDecimal(v);  
     return b.setScale(scale, round_mode).toString();  
  }  
}

四、BigDecimal 舍入模式(Rounding mode)

BigDecimal定义了一下舍入模式,只有在作除法运算或四舍五入时才用到舍入模式,下面简单介绍,详细请查阅J2se API文档
static int
ROUND_CEILING
          Rounding mode to round towards positive infinity.
向正无穷方向舍入
static int
ROUND_DOWN
          Rounding mode to round towards zero.
向零方向舍入
static int
ROUND_FLOOR
          Rounding mode to round towards negative infinity.
向负无穷方向舍入
static int
ROUND_HALF_DOWN
          Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
static int
ROUND_HALF_EVEN
          Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.
向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP ,如果是偶数,使用ROUND_HALF_DOWN
static int
ROUND_HALF_UP
          Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6
static int
ROUND_UNNECESSARY
          Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.
计算结果是精确的,不需要舍入模式
static int
ROUND_UP
          Rounding mode to round away from zero.
向远离0的方向舍入
原文地址:https://www.cnblogs.com/soul-wonder/p/9289043.html