Java BigDecimal

本文深入解析Java中的BigDecimal类,探讨其在商业计算和高精度运算中的应用,对比double类型的局限性,详细介绍BigDecimal的构造方法、小数点后位数与舍入模式,以及加减乘除运算的具体实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、概述

位于java.math包中,用于商业计算等高精度运算,用来对超过16位有效位的数进行精确的运算。

double类型运算
对于上述代码的运行结果如下:
double类型运算结果
可以看出double类型运算会产生一定的误差。原因在于计算机所使用的二进制无法精确表示某些带小数位的十进制数据。比如(0.75)10=(0.11)2,而(0.65)10=(0.101001100110011001100110011001100110011…)2
BigDecimal继承了Number类,实现了Comparable<BigDecimal>接口
在BigDecimal中
scale指的是小数点后的位数。
roundingMode是小数的保留模式。值为BigDecimal中的常量字段。
ROUND_UP:向远离0的方向舍入
ROUND_DOWN:向0方向舍入
ROUND_CEILING:向正无穷方向舍入
ROUND_FLOOR:向负无穷方向舍入
ROUND_HALF_UP:向最近的方向舍入,如果相等,向上舍入
ROUND_HALF_DOWN:向最近的方向舍入,如果相等,向下舍入
ROUND_HALF_EVEN:向最近的方向舍入,如果相等,如果保留位是偶数,则向上舍入,如果是奇数,则向下舍入。
ROUND_UNNECESSARY:计算结果是精确的,不需要舍入模式

2、构造方法

  • public BigDecimal(BigInteger)
  • public BigDecimal(double)
  • public BigDecimal(char[])
  • public BigDecimal(long)
  • public BigDecimal(String)

使用double转换时是会出现误差的。
jdk1.8 中注释如下

/**
  * The results of this constructor can be somewhat unpredictable.
  * One might assume that writing {@code new BigDecimal(0.1)} in
  * Java creates a {@code BigDecimal} which is exactly equal to
  * 0.1 (an unscaled value of 1, with a scale of 1), but it is
  * actually equal to
  * 0.1000000000000000055511151231257827021181583404541015625.
  * This is because 0.1 cannot be represented exactly as a
  * {@code double} (or, for that matter, as a binary fraction of
  * any finite length).  Thus, the value that is being passed
  * <i>in</i> to the constructor is not exactly equal to 0.1,
  * appearances notwithstanding.
  * /
这个构造函数的结果可能是不可预测的。有些人认为new BigDecimal(0.1)正好等于0.1但是它实际上是等
于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能精确的表示
为一个双精度的数。

所以这个构造方法是不建议使用的,通常会转换为String类型(即使用Double.toString(double))或者是使用BigDecimal的静态方法valueOf(double),内部实现和前面一样。

3、加减乘除运算

public static void main(String[] args) {
    BigDecimal decimal = new BigDecimal("0.12");
    BigDecimal decimal1 = new BigDecimal("0.012");

    System.out.println(decimal.add(decimal1));
    System.out.println(decimal.subtract(decimal1));
    System.out.println(decimal.multiply(decimal1));
    System.out.println(decimal.divide(decimal1));
}
/*
0.132
0.108
0.00144
1E+1
*/
### Java 中 `BigDecimal` 的使用方法 #### 创建 `BigDecimal` 创建 `BigDecimal` 对象有多种方式,最推荐的方式是从字符串构建: ```java BigDecimal valueFromString = new BigDecimal("123.45"); ``` 这种方式可以避免浮点数精度丢失的问题[^2]。 #### 基本算术操作 ##### 加法 通过调用 `add()` 方法实现加法运算: ```java BigDecimal sum = b1.add(b2); System.out.println("相加:" + sum); // 结果为 3 ``` ##### 减法 利用 `subtract()` 方法执行减法计算: ```java BigDecimal difference = b2.subtract(b1); System.out.println("相减:" + difference); // 结果为 1 ``` ##### 乘法 乘法可以通过 `multiply()` 完成: ```java BigDecimal product = b2.multiply(b3); System.out.println("相乘:" + product); // 结果为 8 ``` ##### 除法 对于除法,需要注意的是当无法整除时可能会抛出异常。因此建议指定舍入模式来处理这种情况: ```java // 设置精确度并采用四舍五入策略 BigDecimal quotient = b2.divide(b3, 2, RoundingMode.HALF_UP); System.out.println("相除:" + quotient); // 结果约为 0.50 ``` #### 比较大小 要获取两个数值中的较大者可使用 `max()` 方法;同样地,如果想要找到较小的那个则应该选用 `min()`: ```java BigDecimal num = new BigDecimal("3"); BigDecimal num1 = new BigDecimal("4"); // 获取两者之间的最大值 BigDecimal maxValue = num.max(num1); // 获取最小值的方法与此类似 BigDecimal minValue = num.min(num1); ``` #### 处理空指针异常 为了避免因传入 null 参数而导致程序崩溃,在进行任何运算前都应先验证对象是否为空: ```java if (bigDecimal != null && anotherBigDecimal != null){ bigDecimal.add(anotherBigDecimal); } else { throw new IllegalArgumentException("参数不能为空!"); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值