Java 的 BigInteger 符号数值如何工作

Ter*_*ser 4 reverse biginteger bit

考虑以下代码:

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());
Run Code Online (Sandbox Code Playgroud)

输出是:

1 binary: 1
1 reverse bit decimal: -9223372036854775808
1 reverse bit binary: 1000000000000000000000000000000000000000000000000000000000000000
1 Sign-Magnitude BigInteger toString: 9223372036854775808
Run Code Online (Sandbox Code Playgroud)

谁能帮助解释为什么“1 Sign-Magnitude BigInteger toString:”的值为 9223372036854775808 (2^63)?

Rud*_*uis 5

要获取某个值的符号大小,只需将其绝对值作为大小,然后将符号存储在单独的位(或字节)中。

比如说,符号-数值的表示722很简单:

sign = 0
magnitude = 722
Run Code Online (Sandbox Code Playgroud)

的符号大小-722很简单:

sign = 1
magnitude = 722
Run Code Online (Sandbox Code Playgroud)

这也是BigInteger用的。

您的代码反转了一个值,这意味着 8 位值00000001(1) 变为10000000(128 或 2^7)。这与求逆不同,求逆将00000001(1) 变成11111110(254)。这就是补码的作用。一般使用的二进制补码00000001将(1)求反成11111111(255,即256-1)。您应该阅读有关补码的内容,这需要一些理解。然而,符号数值非常容易理解(但并不总是很实用——有符号和无符号的加法、减法是不同的,等等——这就是为什么大多数处理器使用补码的原因)

再说一遍:符号大小的工作原理如下:

sign = (n < 0)
magnitude = abs(n)
Run Code Online (Sandbox Code Playgroud)