java特殊类【BIgInteger】
BigInteger使用总结
一、是什么
BigInteger是Java中一种特殊的包含类,主要用于处理任意精度的整数。它的数据精度比int(32位-231到231-1)和long(64位-263到263-1)大的多,能够存储和处理超过基本数据类型范围的数字。在数学和计算中,这种类型通常被称为大整数。
1.1. 作用
- 处理大整数:由于计算机内部使用固定精度的二进制表示法,对于非常大的整数,超过基本数据类型(如int或long)的范围,无法直接存储和计算。这时就需要使用BigInteger这种数据类型;
- 精确计算:在需要精确计算的场景中,如金融、货币计算、大数分解等,使用BigInteger可以避免由于数据类型精度限制而导致的误差;
- 加密和安全算法:在加密和安全算法中,BigInteger的高精度运算特性使得它可以用于实现加密和解密算法,以及生成安全的随机数等;
- 数学和科学计算:在数学和科学计算中,很多公式和算法需要高精度的整数运算,比如高次方程求解、大数分解等,使用BigInteger可以提高计算的精度和可靠性;
- 灵活的数值范围:igInteger支持任意大小的整数,无论是正数还是负数,因此它可以用于处理非常广泛的数值范围。
注:由于BigInteger使用了大量的内存来存储数字,因此它的性能可能不如基本数据类型。此外,由于BigInteger是静态的,每次使用后必须新建一个实例,不能重复使用已存在的实例。因此,在使用BigInteger时需要权衡精度和性能之间的需求。
二、精度丢失示例代码
2.1. 普通类型计算精度丢失
public class test {
public static void main(String[] args) {
// 创建一个非常大的整数,超过了long的最大值
long largeNum = 9223372036854775807L;
// 将largeNum乘以一个小数,得到一个小数结果
double result = (double) largeNum * 10;
// 输出结果,由于精度限制,结果会有一定的误差
System.out.println(result);
// 使用BigInteger来防止精度丢失
BigInteger bigNum = new BigInteger("9223372036854775807");
BigInteger resultBig = bigNum.multiply(BigInteger.valueOf((10)));
// 输出BigInteger的结果,由于BigInteger的高精度运算特性,结果不会有误差
System.out.println(resultBig);
}
}
输出结果:
2.2. BigInteger计算精度丢失
public class test {
public static void main(String[] args) {
// 创建一个非常大的整数,超过了long的最大值
BigInteger bigNum = new BigInteger("123456789012345678901234567890");
// 将bigNum乘以一个小数,得到一个小数结果
BigInteger result = bigNum.multiply(BigInteger.valueOf((long) 0.1));
// 输出结果,由于精度限制,结果会有一定的误差
System.out.println(result);
}
}
输出结果:
结论:在含有浮点数的预算中会导致计算结果丢失精度,而不是BigInteger自身丢失精度。
三、构造方法
- **BigInteger(String val):**将字符串表示形式转化为BigInteger;
- **BigInteger(byte[] val):**将字节数组表示形式转化为BigInteger;
- **BigInteger(int signum, byte[] magnitude):**将指定符号和字节数组来构造一个BigInteger;
- **BigInteger(int numBits, Random rnd)�:**通过指定位数和随机数生成一个BigInteger。
示例代码:
public class test {
public static void main(String[] args) {
String numStr = "12345678901234567890";
BigInteger bigInt = new BigInteger(numStr);
System.out.println(bigInt);
byte[] bytes = {1, 2, 3, 4, 5};
BigInteger bigByte = new BigInteger(bytes);
System.out.println(bigByte); // 输出
int sign = -1; // 负数符号
byte[] magnitude = {1, 2, 3, 4, 5}; // 绝对值的字节数组
BigInteger bigSign = new BigInteger(sign, magnitude);
System.out.println(bigSign);
int numBits = 100; // 指定位数为100位,生成的随机数将在 [0, 2^100) 的范围内(包含0但不包含2^100)
Random rnd = new Random(); // 创建随机数生成器
// 使用随机数生成器生成一个具有指定位数的随机数
BigInteger bigRandom = new BigInteger(numBits, rnd);
System.out.println(bigRandom);
}
}
输出结果:
四、运算
4.1. 加减乘除
示例代码:
public class test {
public static void main(String[] args) {
//创建两个BigInteger对象
BigInteger bi1 = BigInteger.valueOf(100);
BigInteger bi2 = BigInteger.valueOf(20);
//加法
BigInteger bi3 = bi1.add(bi2);
System.out.println(bi3);
//减法
BigInteger bi4 = bi1.subtract(bi2);
System.out.println(bi4);
//乘法
BigInteger bi5 = bi1.multiply(bi2);
System.out.println(bi3);
//除法 获取商和余数
BigInteger[] arr = bi1.divideAndRemainder(bi2);
System.out.println(arr.length);
System.out.println(arr[0]); //商
System.out.println(arr[1]); //余数
}
}
输出结果:
五、比较大小
5.1. compareTo
public class test {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("123");
BigInteger b2 = new BigInteger("1223");
int result = b1.compareTo(b2);
System.out.println(result);
}
}
输出结果:
5.2. equals
public class test {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("123");
BigInteger b2 = new BigInteger("1223");
boolean result = b1.equals(b2);
System.out.println(result);
}
}
输出结果:
5.3. compareTo和equels区别
compareTo方法比较的是数值大小,不考虑符号。如果当前对象小于参数对象,返回 -1;如果等于,返回 0;如果大于,返回 1。
equles方法则同时考虑数值和符号。只有当两个BigInteger对象的值和符号都相同时,才会返回 true。
六、位运算
6.1. 位运算
public class test {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("1010", 2);
BigInteger b2 = new BigInteger("1100", 2);
BigInteger and = b1.and(b2); //按位与,纵向对比,两位全为1,该位才为1 1000
BigInteger or = b1.or(b2); //按位或,纵向对比,只要有1,该位就为1 1110
BigInteger xor = b1.xor(b2); //按位异或,纵向对比,相同为0,不同为1 0110
//按位取反,逐位取反, 0101,按位取反操作在Java中会根据二进制补码的形式来计算负数(1011)。
// 因此,对于正数,按位取反操作会得到一个负数;对于负数,按位取反操作会得到一个正数
BigInteger not = b1.not();
System.out.println(and);
System.out.println(or);
System.out.println(xor);
System.out.println(not);
}
}
输出结果:
6.2. 位移动
public class test {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("1010", 2);
BigInteger left = b1.shiftLeft(2); //向左移动两个二进制位 101000
BigInteger right = b1.shiftRight(2); //向右移动一个二进制位 0010
System.out.println(left);
System.out.println(right);
}
}
输出结果:
七、注意事项
BigInteger是Java中用于表示任意精度的整数的类。它提供了许多用于操作大整数的静态方法,如加法、减法、乘法、除法、模运算等。它可以用于大数计算、密码学、科学计算和金融领域等场景。
在使用BigInteger时,需要注意以下事项:
- 精度问题:由于BigInteger采用高精度的算法,因此在处理大整数时可能会占用大量内存和计算资源。需要合理控制整数的范围和精度,避免造成不必要的性能损耗。
- 溢出问题:当进行大整数运算时,可能会出现溢出的情况,导致结果不正确。需要合理设计算法和数据结构,避免溢出问题的发生。
- 空指针异常:在使用BigInteger的某些方法时,如toBigInteger()方法,可能会抛出NullPointerException异常。需要在使用这些方法前确保BigInteger对象不为空。
- 精度损失:在进行浮点数和整数的混合运算时,可能会出现精度损失的情况。需要合理选择运算顺序和数据类型,避免精度损失的发生。
- 符号处理:在处理负数时,需要注意符号的处理方式。BigInteger采用二进制补码表示法,符号位在最高位(最左边的一位),其余位表示数值。对于负数,符号位为1,其余位为该数的二进制补码表示。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)