Terminal User
Terminal User

Reputation: 883

How Java's BigInteger sign-magnitude works

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

Answers (1)

Rudy Velthuis
Rudy Velthuis

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

Related Questions