我需要使用按位移位在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构造函数?
答案 0 :(得分:2)
首先要做的事情是:
(1 << (bitsCount)) - 1
这是一个错误,因为您只执行整数运算。你需要:
(1L << (bitsCount)) - 1
但是无论如何我认为bitsCount
是64.在Java中,你不能换一个长于63的数字和一个int(JLS 15.19)的数字:
如果左侧操作数的提升类型为
int
,则只使用右侧操作数的五个最低位作为移位距离。就好像右手操作数受到带有掩码值AND
(&
)的按位逻辑0x1f
运算符0b11111
(第15.22.1节)的影响。因此,实际使用的移动距离始终在0
到31
的范围内,包括在内。如果左侧操作数的提升类型为
long
,则只使用右侧操作数的六个最低位作为移位距离。就好像右手操作数受到带有掩码值AND
(&
)的按位逻辑0x3f
运算符0b111111
(第15.22.1节)的影响。因此,实际使用的移动距离始终在0
到63
的范围内,包括在内。
这就是你得0的原因,因为表达式减少到(1 << 0) - 1
。
您需要以不同的方式计算最大值,例如:
-1L >>> (64 - bitsCount)
或:
BigInteger.ONE.shiftLeft(bitsCount).subtract(BigInteger.ONE)
如果你正在测试一个BigDecimal,那么在这里不要长时间使用它会更安全。