我必须以某种方式处理Java中的8字节无符号整数类型。
我的8字节无符号整数存储在由ByteBuffer包装的字节数组中。它来自数据记录器数据库,并且包含很大的数字。
这是我处理4字节整数以将其读取为无符号整数的方式:
((long) (bytebuffer.getInt() & 0xFFFFFFFFL));
不幸的是,
((BigInteger) (bytebuffer.getLong() & 0xFFFFFFFFFFFFFFFFL));
不起作用。
如何存储数字 2 ^ 64-1 并将其读取为 2 ^ 64-1 ?
答案 0 :(得分:12)
在Java的签名long
中,最高有效位为-(2 63 )。如果未签名,则该位将为正2 63 。区别是2 64 。
首先,使用BigInteger
值创建一个long
。然后,如果为负,则通过在1 << 64
上加上2 64 或BigInteger
来应用无符号校正。
BigInteger result = BigInteger.valueOf(bytebuffer.getLong());
if (result.compareTo(BigInteger.ZERO) < 0) {
result = result.add(BigInteger.ONE.shiftLeft(64));
}
答案 1 :(得分:5)
您可以将其转换为无符号字符串,然后将其解析为BigInteger
:
new BigInteger(Long.toUnsignedString(bytebuffer.getLong()))
可能不是最有效的解决方案,但可能是最简单的解决方案。
或者您可以从Long
类中借用此实现:
static BigInteger toUnsignedBigInteger(long i) {
if (i >= 0L)
return BigInteger.valueOf(i);
else {
int upper = (int) (i >>> 32);
int lower = (int) i;
// return (upper << 32) + lower
return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
}
}