why does BigInteger.bitLength()
print 0
for -1
in Java:
System.out.println(BigInteger.valueOf(-1).bitLength());
there is a comment in the source code for BigInteger that says:
bitLength not initialized yet
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
}
Check the documentation for the BigInteger.bitLength()
method:
Returns the number of bits in the minimal two's-complement representation of this BigInteger, excluding a sign bit. [...]
You need zero "value" bits to represent the value 0
. Basically, you "don't need to do anything" and you have the value 0
. With the sign bit you can switch between 0
and -1
(as similar to the two's-complement).
When you have the value 1
you need one "value" bit, so BigInteger.bitLength()
will return 1
for the BigInteger value 1
. Check the following for
loop and the output it generates:
for (int i=-16; i<=16; i++) {
BigInteger x = BigInteger.valueOf(i);
System.out.println(x+"| bitlength: "+x.bitLength());
}
The output is:
-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