我必须以某种方式处理Java中的8字节无符号整数类型.
我的8字节无符号整数存储在ByteBuffer包装的字节数组中.它来自数据记录器数据库,包含非常大的数字.
这是我如何处理4字节整数将它们作为无符号读取它们:
((long) (bytebuffer.getInt() & 0xFFFFFFFFL));
Run Code Online (Sandbox Code Playgroud)
不幸的是:
((BigInteger) (bytebuffer.getLong() & 0xFFFFFFFFFFFFFFFFL));
Run Code Online (Sandbox Code Playgroud)
不起作用.
如何存储数字2 ^ 64-1并将其读取为2 ^ 64-1?
rge*_*man 12
在Java的签名中long,最重要的一点是值得的 - (2 63).如果它是未签名的,则该位值得为正值2 63.差异是2 64.
首先,创建一个BigInteger使用该long值.然后,如果它是负数,则通过添加2 64来应用无符号校正,或者1 << 64,对于BigInteger.
BigInteger result = BigInteger.valueOf(bytebuffer.getLong());
if (result.compareTo(BigInteger.ZERO) < 0) {
result = result.add(BigInteger.ONE.shiftLeft(64));
}
Run Code Online (Sandbox Code Playgroud)
您可以将其转换为无符号字符串,然后将其解析为BigInteger:
new BigInteger(Long.toUnsignedString(bytebuffer.getLong()))
Run Code Online (Sandbox Code Playgroud)
可能不是最有效的解决方案,但可能是最简单的解决方案.
或者你可以在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)));
}
}
Run Code Online (Sandbox Code Playgroud)