【问题标题】:How can I read a Java long as unsigned and store its value in a BigInteger?如何读取无符号的 Java 并将其值存储在 BigInteger 中?
【发布时间】:2018-07-06 23:03:17
【问题描述】:

我必须以某种方式在 Java 中处理一个 8 字节的无符号整数类型。

我的 8 字节无符号整数存储在由 ByteBuffer 包装的字节数组中。它来自数据记录器数据库,包含非常大的数字。

这就是我处理 4 字节整数以将它们读取为无符号的方式:

((long) (bytebuffer.getInt() & 0xFFFFFFFFL));

不幸的是:

((BigInteger) (bytebuffer.getLong() & 0xFFFFFFFFFFFFFFFFL));

没用。

如何存储数字2^64-1并将其读取为2^64-1

【问题讨论】:

标签: java types


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    在 Java 的签名 longs 中,最高有效位值 -(263)。如果它是无符号的,那么该位的值为正 263。相差 264

    首先,使用long 值创建一个BigInteger。然后,如果它是负数,则通过将 2641 &lt;&lt; 64 添加到 BigInteger 来应用无符号校正。

    BigInteger result = BigInteger.valueOf(bytebuffer.getLong());
    if (result.compareTo(BigInteger.ZERO) < 0) {
        result = result.add(BigInteger.ONE.shiftLeft(64));
    }
    

    【讨论】:

      猜你喜欢
      • 2013-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多