Java的BigInteger如何使用符号-大小表示法

3

考虑以下代码:

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());

输出结果如下:
1 binary: 1
1 reverse bit decimal: -9223372036854775808
1 reverse bit binary: 1000000000000000000000000000000000000000000000000000000000000000
1 Sign-Magnitude BigInteger toString: 9223372036854775808

有人能帮忙解释一下为什么“1 Sign-Magnitude BigInteger toString:”的值是9223372036854775808(2^63)吗?


请了解关于补码和反码的知识,它们在Java中作为int和long等简单类型使用,而BigInteger使用符号-大小表示法。您似乎混淆了反转倒置否定。在二进制补码中,否定意味着倒置并加一。在一的补码中,倒置和否定是一样的。在符号大小表示法中,否定意味着翻转符号位。但是这些操作都不会反转(即将最低位变为最高位等)。 - Rudy Velthuis
1个回答

4
为了得到一个数的符号-大小表示,你只需要取它的绝对值作为大小,并在单独的位(或字节)中记住符号。
例如,722 的符号-大小表示就是:
sign = 0
magnitude = 722
< p > -722 的符号大小只是:

sign = 1
magnitude = 722

那也是BigInteger所使用的方法。
您的代码反转了一个值,这意味着,例如,8位值00000001(1)变为10000000(128或2^7)。这与取反不同,取反将例如00000001(1)变为11111110(254)。这就是补码的作用。通常使用的二进制补码00000001(1)取反为11111111(255,即256-1)。您应该阅读关于二进制补码的资料,这需要一些理解。然而,有符号数的表示法非常容易理解(但不总是非常实用——有符号和无符号的加减法不同等——这就是为什么大多数处理器使用二进制补码的原因)。
所以再次强调:有符号数的表示法如下:
sign = (n < 0)
magnitude = abs(n)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接