Java 在 java.math 包中提供的 API 类 BigDecimal,用来对超过16位有效位的数进行精确的运算

提供以下操作:算术、标度操作、舍入、比较、哈希算法和格式转换。

用户能通过提供 MathContext 对象完全控制 BigDecimal 的舍入行为(也可使用类内提供的8种舍入模式)。如果未指定舍入模式,并且无法表示准确结果,则抛出一个异常。

 

1、构造方法

BigDecimal 一般用如下4个构造方法:

方法名称

方法解释

BigDecimal(int)

创建一个具有参数所指定整数值的对象

BigDecimal(double)

创建一个具有参数所指定双精度值的对象。(不建议采用)

BigDecimal(long)

创建一个具有参数所指定长整数值的对象

BigDecimal(String)

创建一个具有参数所指定以字符串表示的数值的对象

2、加减乘除运算

方法名称

方法解释

public BigDecimal add(BigDecimal value)

加法

public BigDecimal subtract(BigDecimal value)

减法

public BigDecimal multiply(BigDecimal value)

乘法

public BigDecimal divide(BigDecimal value)

除法

   
  
注意: divide 除法需要注意精度,因为存在除不开的情况,这时需要考虑保留位数和舍入模式,需要用到如下方法

public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 第一参数表示除数, 第二个参数表示小数点后保留位数,第三个参数表示舍入模式,只有在作除法运算或四舍五入时才用到舍入模式

 

3、舍入模式

枚举值

解释

原值

保留5位取值

RoundingMode.UP

远离零的舍入模式(向上舍入)。舍弃某部分时,若舍弃部分非零则对其前面的数字加1(此舍入模式始终不会减少计算值的大小)

0.833333...

0.83334

RoundingMode.DOWN

接近零的舍入模式(向下舍入)。直接丢弃需舍弃部分(此舍入模式始终不会增加计算值的大小)

0.833333...

0.83333

RoundingMode.CEILING

接近正无穷大的舍入模式。若BigDecimal为正,则舍入行为同ROUND_UP;若为负,则舍入行为同ROUND_DOWN(此舍入模式始终不会减少计算值大小)

0.833333...

0.83334

-0.833333...

-0.83333

RoundingMode.FLOOR

接近负无穷大(不是无穷小哦)的舍入模式。其行为与ROUND_CEILING相反,若BigDecimal为负,则舍入行为同ROUND_UP;若为正,则舍入行为同ROUND_DOWN(此舍入模式始终不会增加计算值大小)

0.833333...

0.83333

-0.833333...

-0.83334

RoundingMode.HALF_UP

向最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式(四舍五入,即舍弃部分>=0.5则向上舍入,否则向下舍入)

0.9166666...

0.91667

0.833333...

0.83333

RoundingMode.HALF_DOWN

向最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向下舍入的舍入模式(舍弃部分<=0.5则向下舍入,否则向上舍入)

0.9166666..

0.91667

0.833333...

0.83333

RoundingMode.HALF_EVEN

向最接近的数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入(在重复进行一系列计算时,此舍入模式可以将累加错误减到最小)

3.3333333...

3.33333

0.9166666...

0.91667

RoundingMode.UNNECESSARY

断言请求的操作具有精确的结枚,因此不需要舍入,若该操作无精确结果(如1/3)则抛出 ArithmeticException

1

1.00000

0.333333...

ArithmeticException

 

 

java 的 math 包下 RoundingMode枚举类源码如下

public static RoundingMode valueOf(int rm) {
        switch(rm) {

        case BigDecimal.ROUND_UP:
            return UP;

        case BigDecimal.ROUND_DOWN:
            return DOWN;

        case BigDecimal.ROUND_CEILING:
            return CEILING;

        case BigDecimal.ROUND_FLOOR:
            return FLOOR;

        case BigDecimal.ROUND_HALF_UP:
            return HALF_UP;

        case BigDecimal.ROUND_HALF_DOWN:
            return HALF_DOWN;

        case BigDecimal.ROUND_HALF_EVEN:
            return HALF_EVEN;

        case BigDecimal.ROUND_UNNECESSARY:
            return UNNECESSARY;

        default:
            throw new IllegalArgumentException("argument out of range");
        }
    }

从中可以看出它们的对应关系,如、RoundingMode.UP 与 BigDecimal.ROUND_UP 等价

枚举变量名

枚举变量名

常量值

RoundingMode.UP

BigDecimal.ROUND_UP

0

RoundingMode.DOWN

BigDecimal.ROUND_DOWN

1

RoundingMode.CEILING

BigDecimal.ROUND_CEILING

2

RoundingMode.FLOOR

BigDecimal.ROUND_FLOOR

3

RoundingMode.HALF_UP

BigDecimal.ROUND_HALF_UP

4

RoundingMode.HALF_DOWN

BigDecimal.ROUND_HALF_DOWN

5

RoundingMode.HALF_EVEN

BigDecimal.ROUND_HALF_EVEN

6

RoundingMode.UNNECESSARY

BigDecimal.ROUND_UNNECESSARY

7

 

 

4、其他

BigDecimal 可以通过 setScale 方法设置精度及舍入方式

public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
        return setScale(newScale, roundingMode.oldMode);
}

 

5、参考

官方文档     https://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html