Java高精度计算需用BigInteger和BigDecimal:BigInteger处理超长整数,必须用字符串构造,运算调用add/multiply等方法;BigDecimal用于金融计算,构造必须用字符串,除法须指定scale和舍入模式,判等用compareTo。

Java 基础中处理大数字的高精度计算,核心是绕过 int、long、double 等基本类型的位宽与精度限制,改用 java.math 包中的两个不可变引用类型:BigInteger(整数)和 BigDecimal(带小数点的十进制数)。它们不重载运算符,不自动转换,所有操作必须显式调用方法,并严格控制精度行为。
BigInteger:处理超长整数不溢出
适用于阶乘、大ID、密码学、超大计数等纯整数场景:
-
创建要从字符串开始:避免字面量在编译期就被截断,例如
new BigInteger("999999999999999999999999999");若值在long范围内,可用更高效的BigInteger.valueOf(1234567890123456789L) -
运算全靠方法,不许用 + - * /:加法用
a.add(b),乘法用a.multiply(b),幂运算用a.pow(1000)(指数必须是非负int) -
比较不能用 == 或 >:相等用
a.equals(b),大小用a.compareTo(b)(返回 -1/0/1) -
转换需防静默截断:避免
a.longValue()——它会丢精度;应优先用a.longValueExact(),溢出会明确抛ArithmeticException
BigDecimal:金融级小数精度控制
适用于金额、利率、税率等要求结果确定、可复现的十进制计算:
-
构造必须用字符串:
new BigDecimal("199.99")是安全的;new BigDecimal(0.1)是危险的——它把double已有的二进制误差固化下来 -
四则运算全部方法化:加减乘直接调
add()、subtract()、multiply();除法divide()必须指定scale(小数位数)和RoundingMode,例如a.divide(b, 2, RoundingMode.HALF_UP) -
判等别用 equals():因为
new BigDecimal("1.0").equals(new BigDecimal("1"))返回false(scale 不同);推荐用a.compareTo(b) == 0 -
舍入模式按场景选:货币常用
RoundingMode.HALF_EVEN(银行家舍入),普通业务常用RoundingMode.HALF_UP
共性关键原则
两者都基于不可变设计,每次运算都生成新对象,原值不受影响:
立即学习“Java免费学习笔记(深入)”;
-
全程保持类型,不在中间转基本类型:尤其避免“算一半再转
double或long”,那一步就可能丢失精度或引发异常 -
输入来源决定构造方式:用户输入、文件读取、数据库字段——一律先作为字符串拿到,再建
BigInteger或BigDecimal;不要试图用long或double中转 -
性能有代价,但精度不可妥协:它们比基本类型慢,内存开销大;但在金融、合规、密码学等场景,精度是刚性需求,性能优化应在算法层面(如减少对象创建、复用常量)而非退回到
double
常见错误速查
以下写法极易出错,务必规避:
- ❌
new BigDecimal(0.1)→ 改为new BigDecimal("0.1") - ❌
bigA + bigB→ 改为bigA.add(bigB) - ❌
price.divide(rate)(无 scale 和舍入)→ 改为price.divide(rate, 6, RoundingMode.HALF_UP) - ❌
if (a == b)或if (a > b)→ 改为if (a.compareTo(b) == 0)或if (a.compareTo(b) > 0) - ❌
result.longValue()→ 改为result.longValueExact()或确认范围后再转


















