为什么bigInteger没有-1的位长?

时间:2019-09-30 16:47:41

标签: java biginteger

为什么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
            }

2 个答案:

答案 0 :(得分:3)

它返回最小的two's-complement1),不包括符号位,在这种情况下将其设为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