本文目录导读:

在Java中处理超大数值(超出long或double范围)时,建议使用标准库提供的BigInteger(用于整数)和BigDecimal(用于浮点数),这两种类均位于java.math包中。
BigInteger:处理超大整数
当数值超过 Long.MAX_VALUE(9223372036854775807)时,可用BigInteger。
常见操作
import java.math.BigInteger;
public class BigIntegerDemo {
public static void main(String[] args) {
// 通过字符串创建(避免精度丢失)
BigInteger big1 = new BigInteger("123456789012345678901234567890");
BigInteger big2 = BigInteger.valueOf(987654321); // 小数字转为BigInteger
BigInteger big3 = new BigInteger("999999999999999999999999999999");
// 加法
BigInteger sum = big1.add(big3);
System.out.println("相加结果: " + sum);
// 减法
BigInteger diff = big1.subtract(big2);
System.out.println("相减结果: " + diff);
// 乘法
BigInteger product = big1.multiply(big2);
System.out.println("相乘结果: " + product);
// 除法(会截断小数)
BigInteger quotient = big3.divide(big2);
System.out.println("相除结果: " + quotient);
// 获取余数
BigInteger remainder = big3.remainder(big2);
System.out.println("余数: " + remainder);
// 比较大小
int cmp = big1.compareTo(big3);
System.out.println("比较结果: " + cmp); // -1(小于)、0(等于)、1(大于)
// 幂运算
BigInteger power = big2.pow(10);
System.out.println("幂运算: " + power);
// 转换为long(若超出范围会抛出异常)
// long val = big1.longValueExact();
}
}
BigDecimal:处理超高精度浮点数
用于需要精确十进制计算的场景(如金融、科学计算),避免double的精度丢失。
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalDemo {
public static void main(String[] args) {
// 同样使用字符串构造(避免构造时的精度问题)
BigDecimal num1 = new BigDecimal("123456789.1234567890123456789");
BigDecimal num2 = BigDecimal.valueOf(0.1); // 可用,但更推荐字符串
BigDecimal num3 = new BigDecimal("0.1");
// 加法
BigDecimal sum = num1.add(num3);
System.out.println("相加: " + sum);
// 减法
BigDecimal diff = num1.subtract(num2);
System.out.println("相减: " + diff);
// 乘法
BigDecimal product = num1.multiply(num3);
System.out.println("相乘: " + product);
// 除法(必须指定精度和舍入模式)
BigDecimal dividend = new BigDecimal("10");
BigDecimal divisor = new BigDecimal("3");
// 保留20位小数,四舍五入
BigDecimal quotient = dividend.divide(divisor, 20, RoundingMode.HALF_UP);
System.out.println("相除: " + quotient);
// 设置小数位数
BigDecimal rounded = product.setScale(5, RoundingMode.HALF_UP);
System.out.println("四舍五入保留5位小数: " + rounded);
// 比较(不要用equals,用compareTo)
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");
System.out.println("equals比较: " + a.equals(b)); // false(因精度不同)
System.out.println("compareTo比较: " + a.compareTo(b)); // 0(数值相等)
}
}
实际案例:计算阶乘(超过long范围)
import java.math.BigInteger;
public class Factorial {
public static BigInteger factorial(int n) {
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= n; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
public static void main(String[] args) {
// 100! 远超long范围
BigInteger fact100 = factorial(100);
System.out.println("100! = " + fact100);
// 输出:93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
}
}
性能与注意事项
| 特性 | BigInteger / BigDecimal | 原生类型(long / double) |
|---|---|---|
| 性能 | 较慢(对象开销+算法复杂度) | 极快(硬件支持) |
| 存储形式 | 对象(不可变,每次运算创建新对象) | 栈上基本类型 |
| 适用场景 | 超大数 / 精确小数 | 普通数值运算(合理范围内) |
| 内存占用 | 较多(随数值增长而增长) | 固定8字节 |
优化建议:
- 只在必要时使用,业务逻辑中尽量用基本类型
- 避免在循环内频繁创建
BigInteger/BigDecimal(会导致大量对象创建) - 使用
BigDecimal时始终优先用字符串构造,避免new BigDecimal(0.1)的二进制精度问题 - 比较时用
compareTo()而非equals()(equals会检查精度是否一致)
快速决策表
| 需求 | 推荐方案 |
|---|---|
| 超大整数(> 2^63-1) | BigInteger |
| 需要精确的小数计算(金钱) | BigDecimal |
| 普通整数运算(int范围) | int / long |
| 普通浮点运算(不要求高精度) | double / float |
| 需要极高性能的大数运算 | 考虑long+手动溢出检测 |
通过BigInteger和BigDecimal,Java可以处理理论上的任意精度数值(受限于内存大小),适合金融计算、大数运算、科学计算等场景。