目录
问题一:哪些类型的参数能实例化一个BigInteger 对象???
7.判断素数 isProbablePrime(int certainty)
8.返回下一个可能的素数 nextProbablePrime()
前言
本篇博客是笔者对于BigInteger 类学习完后的理解,笔者写作的目的不但是给未来的我去复习查阅,也是为了给愿意点开这篇博客的读者一个良好的学习体验.
如果对您有帮助,希望您可以点赞收藏,如果您发现有错误的地方请私信笔者,核实无误后笔者将给予报酬,也欢迎大佬在评论区中对博客内容补充说明,鄙人将一并感激并给予报酬.
希望您们能从我这篇博客中能了解到BigInter 类的使用.以及笔者是如何进行学习的.
读完本篇博客后,我希望您能了解的
1. 哪些类型的参数能实例化一个BigInteger 对象
2. BigInteger类有哪些常见的方法
话不多说,让我们开始吧!!!!!
问题一:哪些类型的参数能实例化一个BigInteger 对象???
关于这个问题,我们首先打开我们的IDEA,创建一个BigInteger 类后点开它的结构,如图
大家不要觉得看了构造方法的参数类型
就以为int类能或者long类型可以直接实例化BigInteger 对象
笔者先说结论:
BigInteger类是 Java 中用于处理任意精度整数的类。它并不直接支持通过基础数据类型(如 int
或 long
)来构造大整数.
它主要通过以下几种方法
1.String
类型:
通过传入字符串构造 BigInteger
对象,字符串应表示一个整数。
例如:
BigInteger a = new BigInteger(scanner.next());
BigInteger bigInteger = new BigInteger("1234567890");
2. byte[]
类型:
通过传入字节数组构造 BigInteger
对象。字节数组应表示一个整数的二进制形式,数组的第一个字节表示最高位。
byte[] byteArray = { 0x01, 0x02, 0x03 }; // 示例字节数组
BigInteger bigInteger1 = new BigInteger(byteArray);
int value = 12345;
// 将整数转换为字节数组(Big Endian)
byte[] magnitude = ByteBuffer.allocate(4).putInt(value).array();
// 创建 BigInteger 对象,signum 为 1 表示正数
BigInteger bigInteger = new BigInteger(-1, magnitude);
System.out.println("BigInteger value: " + bigInteger);
System.out.println(value);
byte[] byteArray = { 0x01, 0x02, 0x03 }; // 示例字节数组
BigInteger bigInteger1 = new BigInteger(byteArray); // 用字节数组构造 BigInteger 对象
System.out.println(bigInteger1); // 打印结果
接下来是答疑时间:为什么它并不直接支持通过基础数据类型构造?
笔者把源码贴下来大家看看:
public BigInteger(int signum, byte[] magnitude) {
this.mag = stripLeadingZeroBytes(magnitude);
if (signum < -1 || signum > 1)
throw(new NumberFormatException("Invalid signum value"));
if (this.mag.length == 0) {
this.signum = 0;
} else {
if (signum == 0)
throw(new NumberFormatException("signum-magnitude mismatch"));
this.signum = signum;
}
if (mag.length >= MAX_MAG_LENGTH) {
checkRange();
}
}
private BigInteger(int signum, int[] magnitude) {
this.mag = stripLeadingZeroInts(magnitude);
if (signum < -1 || signum > 1)
throw(new NumberFormatException("Invalid signum value"));
if (this.mag.length == 0) {
this.signum = 0;
} else {
if (signum == 0)
throw(new NumberFormatException("signum-magnitude mismatch"));
this.signum = signum;
}
if (mag.length >= MAX_MAG_LENGTH) {
checkRange();
}
}
我们可以看到,这里的 int signum
表示的是 符号(1
为正,-1
为负,0
为零)。
int value = 12345;
// 将整数转换为字节数组(Big Endian)
byte[] magnitude = ByteBuffer.allocate(4).putInt(value).array();
BigInteger bigInteger = new BigInteger(-1, magnitude);
System.out.println("BigInteger value: " + bigInteger);
将输出 -12345,读者们可以粘贴试试
对于long类型
public static BigInteger valueOf(long val) {
// If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant
if (val == 0)
return ZERO;
if (val > 0 && val <= MAX_CONSTANT)
return posConst[(int) val];
else if (val < 0 && val >= -MAX_CONSTANT)
return negConst[(int) -val];
return new BigInteger(val);
}
/**
* Constructs a BigInteger with the specified value, which may not be zero.
*/
private BigInteger(long val) {
if (val < 0) {
val = -val;
signum = -1;
} else {
signum = 1;
}
int highWord = (int)(val >>> 32);
if (highWord == 0) {
mag = new int[1];
mag[0] = (int)val;
} else {
mag = new int[2];
mag[0] = highWord;
mag[1] = (int)val;
}
}
源码说明了,要使用long类参数去构造,首先要将他变为String类型
BigInteger bigInteger2 = new BigInteger(String.valueOf(233232923));
3.它并不直接支持通过基础数据类型构造的原因
以下内容是AI帮我回答的,我的知识不太支持我给出严谨的原因,有错误欢迎指正
1. 支持任意精度的整数
BigInteger
是为了支持任意大小的整数运算而设计的,它可以处理比基础数据类型更大的数字。基础数据类型(如 int
、long
)的存储容量是有限的,而 BigInteger
可以存储和处理任意大小的整数。因此,如果允许直接通过基础数据类型构造 BigInteger
对象,就会限制它的能力。
int
的最大值为2^31 - 1
(即2147483647
)long
的最大值为2^63 - 1
(即9223372036854775807
)
如果允许直接通过这些类型构造 BigInteger
,BigInteger
对象就无法满足其超大数的目标功能。通过基础数据类型构造的 BigInteger
可能会忽略其设计目标,即能够处理无限精度的整数。
2. 不需要额外的 BigInteger
实例化
当你使用 long
类型数值(在 BigInteger
范围内),你实际上可以通过 BigInteger.valueOf(long val)
方法直接得到一个 BigInteger
实例,这个方法会根据常用小整数预先存储常量对象,避免每次都创建新的 BigInteger
实例,提高性能。
例如,如果你只需要处理 0
或 1
,而直接通过 long
类型构造对象可能会导致重复创建相同的 BigInteger
实例。通过 valueOf(long)
,这些常量可以直接复用,避免浪费内存。
3. 数据封装与对象管理
基础数据类型(如 int
、long
)是简单的值类型,而 BigInteger
是一个类,它包含许多方法、字段和与大整数相关的逻辑。直接通过基础数据类型构造 BigInteger
对象,会导致类的封装性丧失。例如,BigInteger
内部的数字是以字节数组(int[]
)存储的,通过基础数据类型直接构造会使得这些复杂的数据管理逻辑无法得到有效利用。
BigInteger
的构造方法接受的是字节数组或其他形式的输入,这种设计能够让它在处理任意大小数字时不依赖于固定大小的内存结构。
4. 性能优化
BigInteger.valueOf(long val)
这个方法通过返回常用的 BigInteger
对象来提高性能。对于特定的 long
值,BigInteger
类内部可能会缓存这些对象,避免重复创建。比如对于常见的数字,如 0
、1
、2
等,它们是预先计算并缓存的,这样能减少不必要的对象创建,提高性能。
如果允许直接使用 long
类型来构造 BigInteger
对象,BigInteger
就需要为每个 long
值都创建一个新的对象,而无法充分利用这些优化。
5. 处理精度的需求
BigInteger
设计的初衷是处理比基本数据类型更大范围的数字。例如,当一个数字超出了 long
的范围时,BigInteger
会继续存储更多的数字,因此它需要更灵活和精确的构造方式。如果直接用基础数据类型构造对象,它的能力就会受限。
问题二,它有哪些实用的,常见的方法???
BigInteger 类提供的方法笔者粗略看了一下都有几十种,在此,笔者介绍几个常用的
注意,许多方法是有方法重载的,笔者仅仅是简单举例.
1.加法 add()
BigInteger a = new BigInteger("100");
BigInteger b = new BigInteger("200");
BigInteger result = a.add(b);
System.out.println(result); // 输出:300
2.减法 subtract()
BigInteger a = new BigInteger("200");
BigInteger b = new BigInteger("100");
BigInteger result = a.subtract(b);
System.out.println(result); // 输出:100
3.乘法 multiply()
BigInteger a = new BigInteger("50");
BigInteger b = new BigInteger("2");
BigInteger result = a.multiply(b);
System.out.println(result); // 输出:100
4.除法 divide()
BigInteger a = new BigInteger("100");
BigInteger b = new BigInteger("20");
BigInteger result = a.divide(b);
System.out.println(result); // 输出:5
5.求快速幂 modPow
快速幂原理笔者介绍过 : 数论, 一篇博客带你初识快速幂,已经为什么需要快速幂-优快云博客
Scanner scanner = new Scanner(System.in);
BigInteger a = new BigInteger(scanner.next());
BigInteger b = new BigInteger(scanner.next());
BigInteger c = new BigInteger(scanner.next());
BigInteger d = a.modPow(b,c);
6.求最大公约数 gcd()
原理直接介绍过: 常见数论模板-gcd,lcm_gcd 代码-优快云博客
BigInteger a = new BigInteger("36");
BigInteger b = new BigInteger("60");
BigInteger result = a.gcd(b);
System.out.println(result); // 输出:12
7.判断素数 isProbablePrime(int certainty)
使用概率算法判断当前 BigInteger
是否为素数。certainty
参数越大,判断越精确
BigInteger a = new BigInteger("23");
if (a.isProbablePrime(100)) {
System.out.println(a + " 是素数");
} else {
System.out.println(a + " 不是素数");
}
8.返回下一个可能的素数 nextProbablePrime()
BigInteger h = new BigInteger("5");
System.out.println(h.nextProbablePrime());
输出 7
结尾
如果你愿意看到这,希望对你有收获,笔者确实是认真总结了,如果对您有帮助,希望您可以点赞收藏,如果您发现有错误的地方请私信笔者,核实无误后笔者将给予报酬,也欢迎大佬在评论区中对博客内容补充说明,鄙人将一并感激并给予报酬.