Reputation: 883
Consider the following code:
int i = 1;
System.out.println("1 binary: " + Long.toBinaryString(i));
long ri = Long.reverse(i);
System.out.println("1 reverse bit decimal: " + ri);
System.out.println("1 reverse bit binary: "+ Long.toBinaryString(ri));
BigInteger bil = new BigInteger(1, Longs.toByteArray(ri));
System.out.println("1 Sign-Magnitude BigInteger toString: " + bil.toString());
The output is:
1 binary: 1
1 reverse bit decimal: -9223372036854775808
1 reverse bit binary: 1000000000000000000000000000000000000000000000000000000000000000
1 Sign-Magnitude BigInteger toString: 9223372036854775808
Can anyone help to explain why the value of "1 Sign-Magnitude BigInteger toString:" is 9223372036854775808 (2^63)?
Upvotes: 4
Views: 2474
Reputation: 28806
To get the sign-magnitude of a value, you simply take its absolute value as magnitude and remember the sign in a separate bit (or byte).
The sign-magnitude representation of, say, 722
is simply:
sign = 0
magnitude = 722
The sign magnitude of -722
is simply:
sign = 1
magnitude = 722
That is also what BigInteger
uses.
Your code reverses a value, which means that, say, the 8 bit value 00000001
(1) is changed into 10000000
(128 or 2^7). That is not the same as inverting, which turns e.g. 00000001
(1) into 11111110
(254). That is what one's complement does. The generally used two's complement negates 00000001
(1) into 11111111
(255, i.e. 256 - 1). You should read up about two's complement, which takes some understanding. Sign-magnitude is, however, very easy to understand (but not always very practical -- addition, subtraction are different for signed and unsigned, etc. -- and that is why most processors use two's-complement)
So again: sign-magnitude works like this:
sign = (n < 0)
magnitude = abs(n)
Upvotes: 5