我有一个场景,我正在使用大整数(例如160位),并试图创建最大可能的无符号整数,可以n在运行时用位数表示.在程序开始执行并从配置文件中读取值之前,不知道n的确切值.例如,n可能是160,或128,或192,等等......
最初我的想法是这样的:
BigInteger.valueOf((long)Math.pow(2, n));
Run Code Online (Sandbox Code Playgroud)
但后来我才意识到,转换为long会发生这种情况有点失败的目的,因为长时间内没有足够的位来存储结果.有什么建议?
我们先来看看这个数字是什么,数学上.
在无符号二进制表示中,最大的n位数将所有位设置为1.让我们看一些示例:
1(2)= 1 =2 1 - 1
11(2)= 3 =2 2 - 1
111(2)= 7 =2 3 - 1
:
1………1(2)=2 n -1
n
请注意,这也类似于十进制.最大的3位数字是:
103- 1 = 1000 - 1 = 999
因此,找到最大n位无符号数的子问题是计算2 n.
由于以下模式,现代数字计算机可以有效地计算两个幂:
2 0
= 1(2)
2 1= 10(2)
2 2= 100(2)
2 3= 1000(2)
:
2 n= 10………0(2)
n
也就是说,2 n只是一个数字,其位n设置为1,其他所有设置为0(请记住,这些位编号为零基索引).
综上所述,我们可以使用这个简单的解决方案来解决BigInteger我们的问题:
final int N = 5;
BigInteger twoToN = BigInteger.ZERO.setBit(N);
BigInteger maxNbits = twoToN.subtract(BigInteger.ONE);
System.out.println(maxNbits); // 31
Run Code Online (Sandbox Code Playgroud)
如果我们使用long,那么我们可以这样写:
// for 64-bit signed long version, N < 64
System.out.println(
(1L << N) - 1
); // 31
Run Code Online (Sandbox Code Playgroud)
没有定义"设置位n "操作long,因此传统上使用位移.事实上,BigInteger这种移位技术的类比也是可能的:
System.out.println(
BigInteger.ONE.shiftLeft(N).subtract(BigInteger.ONE)
); // 31
Run Code Online (Sandbox Code Playgroud)
BigInteger提示BigInteger确实有一种pow计算任意数字的非负功率的方法.如果你在一个模块化环工作,也有modPow和modInverse.
你可以单独setBit,flipBit或只testBit.你可以获得整体bitCount,and与另一个BigInteger和shiftLeft/ shiftRight等等按位执行.
作为奖励,您还可以计算gcd或检查数字isProbablePrime.
总是要记住BigInteger,就像String,是不可改变的.您无法在实例上调用方法,并期望修改该实例.相反,始终将方法返回的结果分配给变量.