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 位实际上是符号位的事实。
我想要做的是将 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 位实际上是符号位的事实。