Java 的 BigInteger 符号幅度如何工作
Posted
技术标签:
【中文标题】Java 的 BigInteger 符号幅度如何工作【英文标题】:How Java's BigInteger sign-magnitude works 【发布时间】:2017-03-14 21:53:31 【问题描述】:考虑以下代码:
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 使用的符号幅度。您似乎混淆了 reverting、inverting 和 negating。在二进制补码中,取反意味着取反和加一。在一个补码中,取反和取反是相同的。在符号幅度中,取反意味着翻转符号位。但是这些都没有revert(即将最低位变为最高位等) 【参考方案1】:要获得一个值的符号大小,您只需将其绝对值作为大小,并在单独的位(或字节)中记住符号。
722
的符号幅度表示很简单:
sign = 0
magnitude = 722
-722
的符号大小很简单:
sign = 1
magnitude = 722
这也是BigInteger
使用的。
您的代码反转一个值,这意味着,例如,8 位值 00000001
(1) 更改为 10000000
(128 或 2^7)。这与 inverting 不同,后者变成例如00000001
(1) 转换为 11111110
(254)。这就是补码的作用。通常使用的二的补码将00000001
(1) 否定为11111111
(255,即256 - 1)。你应该阅读two's complement,这需要一些了解。然而,符号大小很容易理解(但并不总是很实用——有符号和无符号的加减法是不同的,等等——这就是大多数处理器使用二进制补码的原因)
再说一遍:符号幅度的工作原理是这样的:
sign = (n < 0)
magnitude = abs(n)
【讨论】:
以上是关于Java 的 BigInteger 符号幅度如何工作的主要内容,如果未能解决你的问题,请参考以下文章
Java中的大数处理类BigInteger和BigDecimar浅析
Java 大数类BigInteger和BigDecimal的基本函数
店铺业务场景分析BigDecimal是Java提供的一个不变的任意精度的有符号十进制数对象。它提供了四个构造器,有两个是用BigInteger构造接口怎么使用的重载与重写的区别?分别是什么?