Java--BigInteger 超大整数计算

在 Java 中,基本数据类型的整数有固定取值范围:int、long 容量有限,一旦超出最大值就会发生数值溢出,且编译运行不会报错,导致业务数据错乱。

为解决超大整数运算问题,Java 提供了 BigInteger 类(位于 java.math 包),专门用于任意长度的超大整数运算,完美支持无限长度整数的加减乘除、取模、幂运算、位运算、进制转换等操作,是算法竞赛、金融统计、密码学、大数加密场景的核心类。

一、基本类型数值范围与溢出问题

一旦数值超过 long 最大值,基本类型完全无法存储,且溢出静默失效(无报错、结果错误)。

此时必须使用 BigInteger。

二、BigInteger 核心特点

  1. 支持无限大整数:理论上仅受 JVM 内存限制,无数值上限
  2. 不可变类 :所有运算操作不会修改原对象,返回全新 BigInteger 对象
  3. 无运算符号 :不支持 + - * / % 运算符,必须调用专属方法运算
  4. 精度绝对无损:整数运算不存在精度丢失问题
  5. 性能偏低:基于数组存储大数,运算开销远大于基本类型,不适合高频小数值运算

三、BigInteger 对象创建(4 种常用方式)

BigInteger 没有无参构造,必须通过指定数值、字符串、进制、数组创建对象。

1. 普通数值创建

ini 复制代码
// 通过 long 数值创建(适合 long 范围内数值)
BigInteger num1 = BigInteger.valueOf(123456);
// 负数创建
BigInteger num2 = BigInteger.valueOf(-98765);

2. 字符串创建(推荐,支持超大数)

唯一可以直接定义超出 long 范围超大整数的方式,开发首选。

ini 复制代码
// 远超 long 最大值的超大整数
BigInteger bigNum = new BigInteger("999999999999999999999999999999");

3. 指定进制创建

可将指定进制的数字字符串转为十进制 BigInteger。

ini 复制代码
// 将二进制 1010 转为十进制数字
BigInteger binaryNum = new BigInteger("1010", 2);
// 将十六进制转为十进制
BigInteger hexNum = new BigInteger("FF", 16);

4. 系统常量对象(常用)

内置常用常量,无需 new 对象,节省内存:

arduino 复制代码
BigInteger.ZERO;    // 0
BigInteger.ONE;     // 1
BigInteger.TWO;     // 2
BigInteger.TEN;     // 10

四、核心算术运算方法(重点)

所有运算原对象不变,返回新对象,必须接收返回值。

ini 复制代码
BigInteger a = new BigInteger("100000000000000000000");
BigInteger b = new BigInteger("200000000000000000000");

// 1. 加法
BigInteger addRes = a.add(b);

// 2. 减法
BigInteger subRes = a.subtract(b);

// 3. 乘法
BigInteger mulRes = a.multiply(b);

// 4. 除法(整除,只取整数部分)
BigInteger divRes = b.divide(a);

// 5. 取模
BigInteger modRes = b.mod(a);

// 6. 求绝对值
BigInteger absRes = subRes.abs();

// 7. 取反
BigInteger negRes = a.negate();

// 8. 幂运算
BigInteger powRes = a.pow(3);

// 9. 最大/最小值
BigInteger maxRes = a.max(b);
BigInteger minRes = a.min(b);

五、精准除法(整除+余数)

普通 divide 只返回商,divideAndRemainder 可同时获取商和余数,算法高频使用。

ini 复制代码
BigInteger num = new BigInteger("100");
BigInteger divisor = new BigInteger("3");
// 数组:[0]商,[1]余数
BigInteger[] res = num.divideAndRemainder(divisor);
System.out.println("商:" + res[0]);
System.out.println("余数:" + res[1]);

六、数值比较方法

禁止使用 > < == 比较 BigInteger 对象,必须使用专属比较方法。

ini 复制代码
BigInteger x = new BigInteger("888");
BigInteger y = new BigInteger("666");

// compareTo:大于返回1,等于返回0,小于返回-1
int cmp = x.compareTo(y);

// 判断是否相等(推荐,杜绝 == 地址比较坑)
boolean eq = x.equals(y);

// 判断正负、零
boolean zero = x.equals(BigInteger.ZERO);
boolean positive = x.compareTo(BigInteger.ZERO) > 0;
boolean negative = x.compareTo(BigInteger.ZERO) < 0;

七、进制转换与类型转换

1. 十进制转任意进制字符串

ini 复制代码
BigInteger num = new BigInteger("255");
String binary = num.toString(2);   // 转二进制
String oct = num.toString(8);     // 转八进制
String hex = num.toString(16);     // 转十六进制

2. 大数转基本类型

注意:超出基本类型范围会抛异常,转换前需判断范围。

ini 复制代码
// 转 long(范围溢出抛异常)
long longVal = num.longValue();
// 转 int
int intVal = num.intValue();
// 精准判断是否可以转为 long
boolean canLong = num.bitLength() <= 63;

八、位运算与工具方法(算法常用)

scss 复制代码
BigInteger n = new BigInteger("10");

n.and(BigInteger.ONE);      // 与运算
n.or(BigInteger.ZERO);       // 或运算
n.xor(BigInteger.TWO);      // 异或运算
n.not();                    // 取反
n.shiftLeft(2);             // 左移(乘2^2)
n.shiftRight(1);            // 右移(除2)

// 获取二进制位数
int bitLen = n.bitLength();
// 判断是否为素数
boolean prime = n.isProbablePrime(50); // 参数为置信度

九、BigInteger 核心易错点

1. 不可变特性坑

所有运算不改变原对象,不接收返回值等于白算。

ini 复制代码
// 错误写法
BigInteger a = BigInteger.TEN;
a.add(BigInteger.TEN);
System.out.println(a); // 仍然是10

// 正确写法
a = a.add(BigInteger.TEN);

2. 不能用 == 比较数值

== 比较对象地址,equals 比较数值内容,必须用 equals / compareTo。

3. 禁止基本类型运算符

BigInteger 是对象,不支持 + - * /,编译直接报错,必须调用方法。

4. 超大数必须字符串构造

超出 long 范围的数值,不能用 valueOf/数字直接赋值,只能用字符串构造。

十、BigInteger 与基本类型选型规范

  • 普通数值、范围在 long 内:优先使用 long,性能极高
  • 数值超大、超出 long 范围:必须使用 BigInteger
  • 频繁循环运算、高性能场景:尽量规避 BigInteger,优先基本类型
  • 算法题、大数加密、进制运算、素数判断:首选 BigInteger

十一、总结

  1. BigInteger 是 java.math 包下的超大整数不可变类,解决基本类型数值溢出问题。
  2. 所有运算均返回新对象,原数据不改变,必须接收返回值。
  3. 无运算符重载,所有加减乘除、位运算、比较均需调用专属 API。
  4. 支持任意进制转换、素数判断、幂运算、精准取余,是算法与加密开发必备。
  5. 缺点是性能弱于基本类型,仅用于大数场景,不适合高频小数值运算。
相关推荐
Elastic 中国社区官方博客12 分钟前
我们如何通过 70 多个拉取请求,将 OpenTelemetry Java agent 迁移到 invokedynamic
java·大数据·开发语言·elasticsearch·搜索引擎·全文检索·es
tyn18824 分钟前
记录本地安装nacos服务的方法及异常
java·开发语言
步行cgn1 小时前
Spring MVC 视图机制的核心接口与类
java·开发语言·后端·spring·mvc
y1su1 小时前
Leetcode 字符串模板
java·数据结构·算法·leetcode·职场和发展·动态规划
residual_fan2 小时前
船用柴油机动态机动工况故障诊断:控制感知仿射网络(CAAN)的技术实现
人工智能·算法·数据挖掘·数据分析
其实防守也摸鱼2 小时前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全
我命由我123452 小时前
Python 开发 - Python 的 pathlib
java·开发语言·后端·python·学习·java-ee·学习方法
蓝悦无人机3 小时前
《Planning algorithms》读书笔记——第8章 反馈运动规划
算法·读书笔记·反馈运动规划
RaaS1003 小时前
Agent Skills 进了 Linux Foundation:2.8 亿次安装,但装 skill 还没有安全规范
人工智能·算法·架构
苜蓿muxu3 小时前
Java 字符串拼接:+、StringBuilder、StringBuffer的区别
java