BigInteger.longValue() 是否保证保留 2^63 <= x <= 2^64-1 的无符号二进制?

Is BigInteger.longValue() guaranteed to preseve the unsigned binary for 2^63 <= x <= 2^64-1?

我想要做的是将 64 位无符号整数存储为 Long 类型,保留其区间二进制表示形式

比如我要保存

2^63-1 = 9223372036854775807 原样 (9223372036854775807) (∵ 2^63-1 <= Long.MAX_VALUE)

2^63 = 9223372036854775808 = 10000000 00000000 000000000000000000000000000000000000000000000000000000000000000000000000000000来小视000000000000000000来 因为 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000(2) 是 -9223372036854775808 的带符号 64 位 = 整数类型的二进制表示形式].[=

同样,我想将 2^64-1 = 18446744073709551615 保存为 -1
因为(无符号)18446744073709551615 = 0xFFFFFFFFFFFFFFFF 和(有符号长)-1 = 0xFFFFFFFFFFFFFFFF

BigInteger.longValue() 的 JavaDoc 说

Converts this BigInteger to a long. This conversion is analogous to a narrowing primitive conversion from long to int as defined in section 5.1.3 of The Java™ Language Specification: if this BigInteger is too big to fit in a long, only the low-order 64 bits are returned. Note that this conversion can lose information about the overall magnitude of the BigInteger value as well as return a result with the opposite sign.

但是,我不确定它能否保证按我的预期工作。

BigInteger(string).longValue() 是否足以满足我的目的,其中 string 是原始整数的字符串表示形式?


更新:我使用的是JDK 1.7,所以Long.parseUnsignedLong()不可用。

您应该在 Long class 中使用 unsigned long 方法。

String s = "18446744073709551615"; // 2^64 - 1
long value = Long.parseUnsignedLong(s);
System.out.println("long value = " + value);
System.out.println("unsigned long value = " + Long.toUnsignedString(value));

结果

long value = -1
unsigned long value = 18446744073709551615

在这种情况下,我只 运行 代码,看看会发生什么。

println(new BigInteger("2").pow(63).longValue());
println(new BigInteger("2").pow(63).subtract(new BigInteger("1")).longValue());
println(new BigInteger("2").pow(64).longValue());
println(new BigInteger("2").pow(64).subtract(new BigInteger("1")).longValue());

产出

-9223372036854775808
9223372036854775807
0
-1

所以是的,BigInteger.longValue() 完全按照您的想法行事(并且根据文档的阅读,这是有保证的行为。AKA,它被转换为位数组,并且仅保留低 64 位并用作 long 值,忽略第 64 位实际上是符号位的事实。