按位移位以获得最大无符号值

时间:2014-11-18 16:06:04

标签: java bit-manipulation

我需要使用按位移位在java中为无符号64位长生成最大值。所以这是我的功能:

public static final boolean isMaxLimitMiss(int bitsCount, BigDecimal value, int signum) {
    if (signum == 0) {
        BigDecimal val = new BigDecimal(Long.valueOf((1 << (bitsCount)) - 1));

        return Long.compareUnsigned(value.longValue(), val.longValue()) > 0 ? true : false;
    }

    return value.compareTo(new BigDecimal((1L << (bitsCount - 1)) - 1)) > 0 ? true : false;
}

只检查 的范围是 bitsCount 提供的最大值。 它适用于签名数据。 在64位和无符号的情况下(是的,在java中没有unsigned long。我试图模拟它) - 它是不正确的。 ((1 << (bitsCount)) - 1评估为0

如何将 value = 2 ^ 64 - 1 传递给BigDecimal构造函数?

1 个答案:

答案 0 :(得分:2)

首先要做的事情是:

(1 << (bitsCount)) - 1

这是一个错误,因为您只执行整数运算。你需要:

(1L << (bitsCount)) - 1

但是无论如何我认为bitsCount是64.在Java中,你不能换一个长于63的数字和一个int(JLS 15.19)的数字:

  

如果左侧操作数的提升类型为int,则只使用右侧操作数的五个最低位作为移位距离。就好像右手操作数受到带有掩码值AND&)的按位逻辑0x1f运算符0b11111(第15.22.1节)的影响。因此,实际使用的移动距离始终在031的范围内,包括在内。

     

如果左侧操作数的提升类型为long,则只使用右侧操作数的六个最低位作为移位距离。就好像右手操作数受到带有掩码值AND&)的按位逻辑0x3f运算符0b111111(第15.22.1节)的影响。因此,实际使用的移动距离始终在063的范围内,包括在内。

这就是你得0的原因,因为表达式减少到(1 << 0) - 1

您需要以不同的方式计算最大值,例如:

-1L >>> (64 - bitsCount)

或:

BigInteger.ONE.shiftLeft(bitsCount).subtract(BigInteger.ONE)

如果你正在测试一个BigDecimal,那么在这里不要长时间使用它会更安全。