好,那我给你整理一份 Java BigDecimal
详解,特别针对加、减、乘、除以及小数舍入模式(RoundingMode),带上代码示例 + 注意事项,保证你用起来不踩坑。
1. BigDecimal 作用
- 主要用于 精确表示和计算小数(金融、金额、精度敏感计算)
- 不要用
float
/double
做精确运算(会有二进制精度误差) - BigDecimal 内部用 任意精度的整数 + 小数位数 来存储
2. 创建 BigDecimal(推荐写法)
import java.math.BigDecimal;
public class Demo {
public static void main(String[] args) {
// 推荐:用字符串构造,避免精度丢失
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
System.out.println(a.add(b)); // 0.3
}
}
❌ 不要用 new BigDecimal(0.1)
,因为 0.1
作为 double
已经有误差。
3. 加、减、乘、除
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalOps {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("10.25");
BigDecimal b = new BigDecimal("3");
// 加法
BigDecimal sum = a.add(b); // 13.25
// 减法
BigDecimal diff = a.subtract(b); // 7.25
// 乘法
BigDecimal product = a.multiply(b); // 30.75
// 除法(必须指定精度和舍入模式,否则可能抛 ArithmeticException)
BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP); // 3.42
System.out.println("加法: " + sum);
System.out.println("减法: " + diff);
System.out.println("乘法: " + product);
System.out.println("除法: " + result);
}
}
4. 常用舍入模式(RoundingMode)
模式 | 说明 | 示例(2 位小数) |
---|---|---|
RoundingMode.UP | 远离 0 舍入(只要有多余位就进 1) | 1.234 → 1.24 |
RoundingMode.DOWN | 趋向 0 舍入(直接截断) | 1.239 → 1.23 |
RoundingMode.CEILING | 向正无穷大舍入 | 1.231 → 1.24,-1.239 → -1.23 |
RoundingMode.FLOOR | 向负无穷大舍入 | 1.239 → 1.23,-1.231 → -1.24 |
RoundingMode.HALF_UP | 四舍五入(>=0.5 进 1) | 1.235 → 1.24 |
RoundingMode.HALF_DOWN | 五舍六入(>0.5 进 1) | 1.235 → 1.23 |
RoundingMode.HALF_EVEN | 银行家舍入(0.5 时取偶数) | 1.225 → 1.22,1.235 → 1.24 |
5. 常用 API 速查表
a.add(b) // 加
a.subtract(b) // 减
a.multiply(b) // 乘
a.divide(b, scale, mode) // 除,指定精度 & 舍入
a.setScale(scale, mode) // 改变小数位数 & 舍入
a.compareTo(b) // 比较大小(返回 -1, 0, 1)
a.equals(b) // 严格相等(值 & 小数位数都相等)
a.stripTrailingZeros() // 去掉多余的 0
a.toPlainString() // 以字符串返回,不用科学计数法
6. 实战示例(金额计算)
import java.math.BigDecimal;
import java.math.RoundingMode;
public class MoneyCalc {
public static void main(String[] args) {
BigDecimal price = new BigDecimal("19.99");
BigDecimal quantity = new BigDecimal("3");
BigDecimal total = price.multiply(quantity); // 59.97
BigDecimal discount = new BigDecimal("0.15"); // 15% 折扣
BigDecimal finalPrice = total.multiply(BigDecimal.ONE.subtract(discount))
.setScale(2, RoundingMode.HALF_UP);
System.out.println("总价: " + total);
System.out.println("折后价: " + finalPrice);
}
}
输出:
总价: 59.97
折后价: 50.97
7. 注意事项
- 避免使用
double
/float
构造 BigDecimal- 错误:
new BigDecimal(0.1); // 精度有误
- 正确:
new BigDecimal("0.1"); BigDecimal.valueOf(0.1); // 内部转成 String,精度安全
- 错误:
- 除法必须指定精度和舍入模式
equals
和compareTo
区别equals
:值 & 小数位都要相等compareTo
:只比数值大小
发表回复