news 2026/5/24 15:01:12

java学习--BigInteger和BigDecimal

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java学习--BigInteger和BigDecimal

Java 中处理超出基本数据类型范围的超大整数 / 超大小数,Java 提供了专门的java.math包来解决该问题,核心是两个类:BigInteger(超大整数)、BigDecimal(超大小数),下面从核心用法、场景对比、实战案例到避坑技巧全面讲解。

一、核心类基础认知

✅ 1. BigInteger 类(超大整数处理)

  • 作用:处理任意长度、无精度丢失的整数,突破long(最大 9223372036854775807)的取值上限 / 下限。
  • 适用场景:超大整数运算(密码学、高精度计数、大数幂运算等)。
  • 核心特点:不可变类(所有运算都会返回新对象,原对象不修改)、支持所有整数运算 + 取模 / 素数检测 / 进制转换等特殊操作。

✅ 2. BigDecimal 类(超大小数 / 高精度小数处理)

  • 作用:处理任意精度的十进制小数,彻底解决float/double精度丢失问题(如0.1+0.2≠0.3)。
  • 适用场景:金融计算、金额结算、科学计算、高精度小数运算等(必须用此类型,禁止用浮点型)。
  • 核心特点:不可变类、支持精准小数运算、可自定义舍入模式、控制小数精度。

✅ 3. 与基本数据类型的核心区别

类型取值范围精度问题适用场景
byte/int/long固定有限范围无(整数)常规小数值整数运算
float/double范围大有(浮点丢失)非精准的科学计算
BigInteger无限制超大整数精准运算
BigDecimal无限制小数 / 金额精准运算

二、BigInteger 完整使用教程

1. 对象创建(3 种常用方式)

BigInteger不能直接用赋值号创建,必须通过构造方法静态方法初始化,核心方式如下:

import java.math.BigInteger; public class BigIntegerDemo { public static void main(String[] args) { // 方式1:字符串构造(最常用,支持超大数值)✅ 推荐 BigInteger big1 = new BigInteger("123456789012345678901234567890"); // 方式2:基本类型转换(int/long) BigInteger big2 = BigInteger.valueOf(100L); // 方式3:特殊常量(0、1、10,直接调用,性能更高) BigInteger zero = BigInteger.ZERO; BigInteger one = BigInteger.ONE; BigInteger ten = BigInteger.TEN; } }

2. 核心运算方法(加减乘除 / 取模 / 幂等)

BigInteger不支持+、-、*、/运算符,必须调用类内封装的方法,所有方法返回新的 BigInteger 对象(原对象不变):

public static void main(String[] args) { BigInteger a = new BigInteger("1000000000000000000"); BigInteger b = new BigInteger("2000000000000000000"); // 1. 加法:a + b BigInteger add = a.add(b); // 2. 减法:a - b BigInteger sub = a.subtract(b); // 3. 乘法:a * b BigInteger mul = a.multiply(b); // 4. 除法:a / b(整除,无余数) BigInteger div = b.divide(a); // 5. 取模:a % b BigInteger mod = a.mod(b); // 6. 幂运算:a^3(a的3次方) BigInteger pow = a.pow(3); // 7. 绝对值 BigInteger abs = new BigInteger("-999").abs(); // 8. 比较大小(返回0相等,1>a大,-1>a小) int compare = a.compareTo(b); System.out.println("加法结果:" + add); System.out.println("幂运算结果:" + pow); }

3. 常用特殊操作

BigInteger 内置了大量实用工具方法,满足大数场景的特殊需求:

public static void main(String[] args) { BigInteger num = new BigInteger("123456"); BigInteger target = new BigInteger("7"); // 1. 进制转换:10进制 → 2进制/16进制 String binary = num.toString(2); // 二进制 String hex = num.toString(16); // 十六进制 // 2. 最大公约数(GCD) BigInteger gcd = num.gcd(target); // 3. 素数检测(isProbablePrime(确定性),参数越大越精准,一般传50即可) boolean isPrime = new BigInteger("9973").isProbablePrime(50); // 4. 取反(相反数) BigInteger negate = num.negate(); System.out.println("10进制转2进制:" + binary); System.out.println("是否为素数:" + isPrime); }

三、BigDecimal 完整使用教程(重点,金融必备)

✅ 核心前置知识(必看)

  1. 禁止用double构造 BigDecimalnew BigDecimal(0.1)会得到0.10000000000000000555...,因为double本身存在精度丢失;
  2. 推荐用「字符串构造」new BigDecimal("0.1")才能得到精准的0.1
  3. 舍入模式必须指定:除法 / 保留小数时,若无法整除,必须显式指定舍入模式,否则会抛出ArithmeticException
  4. 不可变性:运算后返回新对象,原对象不修改。

1. 对象创建(3 种方式,区分优劣)

import java.math.BigDecimal; public class BigDecimalDemo { public static void main(String[] args) { // ❌ 错误方式:double构造,存在精度丢失 BigDecimal bad = new BigDecimal(0.1); // ✅ 推荐方式1:字符串构造(精准,无丢失) BigDecimal good1 = new BigDecimal("0.1"); // ✅ 推荐方式2:基本类型转换(int/long,无精度问题) BigDecimal good2 = BigDecimal.valueOf(100); // 等价于 new BigDecimal("100") // ✅ 推荐方式3:特殊常量 BigDecimal zero = BigDecimal.ZERO; BigDecimal one = BigDecimal.ONE; BigDecimal ten = BigDecimal.TEN; System.out.println("错误构造:" + bad); // 输出:0.1000000000000000055511151231257827021181583404541015625 System.out.println("正确构造:" + good1); // 输出:0.1 } }

2. 核心运算方法(加减乘除)

同样不支持运算符,需调用封装方法,除法必须指定舍入模式

public static void main(String[] args) { BigDecimal a = new BigDecimal("0.1"); BigDecimal b = new BigDecimal("0.2"); BigDecimal c = new BigDecimal("3"); // 1. 加法:0.1 + 0.2 = 0.3 ✅ 精准 BigDecimal add = a.add(b); // 2. 减法:0.2 - 0.1 = 0.1 BigDecimal sub = b.subtract(a); // 3. 乘法:0.1 * 0.2 = 0.02 BigDecimal mul = a.multiply(b); // 4. 除法:必须指定【舍入模式】,示例:1 ÷ 3 保留2位小数 BigDecimal div = BigDecimal.ONE.divide(c, 2, BigDecimal.ROUND_HALF_UP); System.out.println("0.1+0.2=" + add); // 输出:0.3 System.out.println("1÷3=" + div); // 输出:0.33 }

3. 关键核心:舍入模式(常用 6 种)

舍入模式是 BigDecimal 的重中之重,决定了小数的取舍规则,金融场景优先用ROUND_HALF_UP(四舍五入),所有舍入模式均为BigDecimal的静态常量:

舍入模式常量含义示例(保留 2 位)
ROUND_HALF_UP ✅(推荐)四舍五入(银行家常用)2.346 → 2.35
ROUND_UP向上进 1(远离 0)2.341 → 2.35
ROUND_DOWN向下截断(靠近 0)2.349 → 2.34
ROUND_HALF_DOWN五舍六入2.345 → 2.34;2.346→2.35
ROUND_CEILING向上取整(正无穷方向)-2.34 → -2.34;2.34→2.35
ROUND_FLOOR向下取整(负无穷方向)-2.34 → -2.35;2.34→2.34

4. 高频实用操作(格式化 / 精度控制 / 比较)

(1)设置小数精度(保留指定位数,指定舍入模式)
// 保留2位小数,四舍五入 BigDecimal num = new BigDecimal("123.4567"); BigDecimal result = num.setScale(2, BigDecimal.ROUND_HALF_UP); System.out.println(result); // 输出:123.46
(2)比较大小(必须用compareTo,禁止用equals
  • equals既比较值,又比较精度0.10.10判定为不相等);
  • compareTo仅比较数值大小(推荐,返回值规则同 BigInteger)。
public static void main(String[] args) { BigDecimal d1 = new BigDecimal("0.1"); BigDecimal d2 = new BigDecimal("0.10"); // ❌ 错误:equals比较精度,返回false System.out.println(d1.equals(d2)); // false // ✅ 正确:compareTo仅比较数值,返回0(相等) System.out.println(d1.compareTo(d2) == 0); // true // 大于/小于判断 boolean gt = new BigDecimal("1.2").compareTo(new BigDecimal("1.1")) > 0; // true boolean lt = new BigDecimal("1.2").compareTo(new BigDecimal("1.3")) < 0; // true }
(3)转基本类型(int/long/double)
BigDecimal big = new BigDecimal("100.99"); int intVal = big.intValue(); // 转int(截断小数)→ 100 long longVal = big.longValue(); // 转long →100 double doubleVal = big.doubleValue(); // 转double(可能丢失精度)→100.99

四、BigInteger vs BigDecimal 核心区别(选型依据)

维度BigIntegerBigDecimal
处理数据类型纯整数(无小数)整数 + 小数(任意精度)
核心优势超大整数无限制运算精准小数运算、解决浮点丢失
关键参数无精度参数需指定精度+舍入模式
核心场景密码学、大数幂运算、进制转换金融金额、高精度小数计算
特殊能力素数检测、最大公约数小数格式化、精度控制

选型口诀

  • 只算整数,且数值超long→ 用BigInteger
  • 涉及小数 / 金额 / 精准浮点 → 必用BigDecimal
  • 常规小数值整数 → 直接用int/long

五、常见坑点 & 避坑指南(必看)

❌ 坑 1:用double构造 BigDecimal

→ ✅ 解决:统一用字符串构造new BigDecimal("xxx")

❌ 坑 2:BigDecimal 除法未指定舍入模式

→ ✅ 解决:除法必须传 3 个参数divide(除数, 保留位数, 舍入模式)

❌ 坑 3:用equals比较 BigDecimal 大小

→ ✅ 解决:用compareTo方法比较,a.compareTo(b) == 0表示相等。

❌ 坑 4:忽略大数的不可变性,直接赋值运算结果

→ ✅ 解决:大数运算后必须接收返回值,如BigInteger c = a.add(b),而非直接a.add(b)

❌ 坑 5:过度使用大数类,常规场景用 BigInteger/BigDecimal

→ ✅ 解决:int/long/float/double能满足的场景,优先用基本类型(性能更高)。

六、实战案例(2 个高频场景)

案例 1:超大整数幂运算(计算 100^20)

BigInteger base = BigInteger.valueOf(100); BigInteger result = base.pow(20); System.out.println("100^20 = " + result); // 输出:10000000000000000000000000000000000000000000000000

案例 2:金融金额计算(订单结算:原价 - 折扣 + 税费,保留 2 位小数)

public static void main(String[] args) { // 订单原价、折扣、税费(均用字符串构造) BigDecimal price = new BigDecimal("999.99"); BigDecimal discount = new BigDecimal("50.5"); BigDecimal tax = new BigDecimal("23.68"); // 计算最终金额:原价 - 折扣 + 税费,保留2位小数,四舍五入 BigDecimal finalPrice = price.subtract(discount).add(tax) .setScale(2, BigDecimal.ROUND_HALF_UP); System.out.println("最终订单金额:¥" + finalPrice); // 输出:¥973.17 }

总结

  1. Java 大数处理依赖java.math包的BigInteger(超大整数)和BigDecimal(高精度小数);
  2. 两者均为不可变类,运算后需接收返回值,不支持基础运算符;
  3. BigDecimal 是金融开发必备,核心是「字符串构造」+「指定舍入模式」;
  4. 大数类虽能解决精度 / 范围问题,但性能低于基本类型,按需使用;
  5. 核心避坑:BigDecimal 不用 double 构造、除法指定舍入模式、用 compareTo 比较大小。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 8:47:34

YOLO结合DeepSORT实现多目标跟踪:完整项目部署教程

YOLO结合DeepSORT实现多目标跟踪&#xff1a;完整项目部署教程 在智能监控系统日益普及的今天&#xff0c;如何让摄像头“看懂”画面中每一个移动对象的身份与轨迹&#xff1f;这不仅是安防领域的核心需求&#xff0c;也深刻影响着智慧交通、零售分析和工业自动化的发展。传统方…

作者头像 李华
网站建设 2026/5/21 6:09:08

YOLO训练数据去重:使用GPU加速哈希比对

YOLO训练数据去重&#xff1a;使用GPU加速哈希比对 在构建高性能目标检测模型的实践中&#xff0c;我们常常把注意力集中在网络结构优化、超参数调优和推理部署上&#xff0c;却容易忽略一个“不起眼”但影响深远的问题——训练数据中的重复样本。 想象这样一个场景&#xff1a…

作者头像 李华
网站建设 2026/5/10 22:53:05

YOLOv10引入PGI机制,提升小目标检测能力,GPU负担加重?

YOLOv10引入PGI机制&#xff0c;提升小目标检测能力&#xff0c;GPU负担加重&#xff1f; 在工业质检线上&#xff0c;一台高速相机每秒拍摄数十帧PCB板图像&#xff0c;系统需要精准识别出小于20像素的虚焊点——这类微小缺陷一旦漏检&#xff0c;可能导致整批产品返工甚至设…

作者头像 李华
网站建设 2026/5/22 1:25:50

YOLO目标检测评估数据集推荐:COCO、Pascal VOC

YOLO目标检测评估数据集推荐&#xff1a;COCO、Pascal VOC 在智能摄像头自动识别行人与车辆的今天&#xff0c;我们很少会去想——这个“看见”的能力从何而来&#xff1f;背后支撑这一切的&#xff0c;是一套高度标准化的技术体系&#xff1a;以YOLO为代表的实时检测模型&…

作者头像 李华
网站建设 2026/5/24 13:32:12

YOLO训练Batch Size设多少?取决于你的GPU显存大小

YOLO训练Batch Size设多少&#xff1f;取决于你的GPU显存大小 在工业质检车间里&#xff0c;一台搭载RTX 3060的工控机正试图训练YOLOv8m模型。工程师满怀期待地启动训练脚本&#xff0c;几秒后终端却弹出一行红色错误&#xff1a;CUDA out of memory。这并非个例——无数开发者…

作者头像 李华
网站建设 2026/5/22 0:52:50

YOLO训练任务支持可视化进度条与ETA预估

YOLO训练任务支持可视化进度条与ETA预估 在工业质检产线的深夜运维室里&#xff0c;工程师盯着终端屏幕上静止的日志输出&#xff0c;心里反复盘问&#xff1a;“这模型到底还在不在跑&#xff1f;是卡住了还是正常收敛&#xff1f;”这种“黑箱式”训练体验&#xff0c;在早期…

作者头像 李华