如何将Java读取为无符号并将其值存储在BigInteger中?

Kam*_*mil 10 java types

我必须以某种方式处理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)


shm*_*sel 5

您可以将其转换为无符号字符串,然后将其解析为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)