为什么BigInteger.bitLength()
在Java中为0
打印-1
:
System.out.println(BigInteger.valueOf(-1).bitLength());
BigInteger的源代码中有一条注释:
bitLength尚未初始化
public int bitLength() {
int n = bitLengthPlusOne - 1;
if (n == -1) { // bitLength not initialized yet
int[] m = mag;
int len = m.length;
if (len == 0) {
n = 0; // offset by one to initialize
}
答案 0 :(得分:3)
它返回最小的two's-complement(1
),不包括符号位,在这种情况下将其设为0。 -1的二进制值是0xFFFF...
/ 0b1111...
,一个人的补数(max-value)变为0
,它加到1
上成为两个人的补数(一个补码+ 1)。
但是,n
中的#bitLength
变量不是您的BigInteger的值,而是存储的bitLength字段的值减去1(并且0
表示尚未计算出该值) )。因此,对于值为BigInteger
的{{1}}从-1
返回0
而言,它们是使用-1作为标准值的巧合。
他们使用此值表示该字段尚未lazily initialized,然后将#bitLength
字段设置为正确的值(0)。请记住,bitLength
是不可变的,因此在计算bitLength时,该实例将永远不会更改。
答案 1 :(得分:3)
检查items(multi=False)
方法的文档:
返回此BigInteger的最小2补码表示形式的位数,不包括一个符号位。 [...]
您需要零个“值”位来表示值0
。基本上,您“不需要执行任何操作”,并且您拥有值0
。使用符号位可以在0
和-1
之间切换(类似于两者的补码)。
当您拥有值1
时,您需要一个“值”位,因此BigInteger.bitLength()
将返回1
作为BigInteger值1
。检查以下for
循环及其产生的输出:
for (int i=-16; i<=16; i++) {
BigInteger x = BigInteger.valueOf(i);
System.out.println(x+"| bitlength: "+x.bitLength());
}
输出为:
-16| bitlength: 4
-15| bitlength: 4
-14| bitlength: 4
-13| bitlength: 4
-12| bitlength: 4
-11| bitlength: 4
-10| bitlength: 4
-9| bitlength: 4
-8| bitlength: 3
-7| bitlength: 3
-6| bitlength: 3
-5| bitlength: 3
-4| bitlength: 2
-3| bitlength: 2
-2| bitlength: 1
-1| bitlength: 0
0| bitlength: 0 /* 0b */
1| bitlength: 1 /* 0b1 */
2| bitlength: 2
3| bitlength: 2 /* 0b11 */
4| bitlength: 3
5| bitlength: 3
6| bitlength: 3
7| bitlength: 3 /* 0b111 */
8| bitlength: 4
9| bitlength: 4
10| bitlength: 4
11| bitlength: 4
12| bitlength: 4
13| bitlength: 4
14| bitlength: 4
15| bitlength: 4 /* 0b1111 */
16| bitlength: 5