我需要使用按位移位在 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 位,对于 unsigned (是的,java 中没有 unsigned long。我试图模拟它) - 这是不正确的。 ((1 << (bitsCount)) - 1
计算结果为 0
如何将 value = 2^64 - 1 传递到 BigDecimal 构造函数中?
最佳答案
第一件事:
(1 << (bitsCount)) - 1
这是一个错误,因为您只执行整数算术。您需要:
(1L << (bitsCount)) - 1
但无论如何我假设 bitsCount
是 64。在 Java 中,对于 long,您不能移动大于 63 的数字;对于 int,您不能移动大于 31 的数字 ( JLS 15.19 ):
If the promoted type of the left-hand operand is
int
, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logicalAND
operator&
(§15.22.1) with the mask value0x1f
(0b11111
). The shift distance actually used is therefore always in the range0
to31
, inclusive.If the promoted type of the left-hand operand is
long
, then only the six lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logicalAND
operator&
(§15.22.1) with the mask value0x3f
(0b111111
). The shift distance actually used is therefore always in the range0
to63
, inclusive.
这就是为什么你得到 0,因为表达式被简化为 (1 << 0) - 1
.
您需要以不同的方式计算最大值,例如:
-1L >>> (64 - bitsCount)
或者:
BigInteger.ONE.shiftLeft(bitsCount).subtract(BigInteger.ONE)
如果您正在测试 BigDecimal,那么在这里完全不要使用 long 会更安全。
关于java - 按位移位以获得最大无符号值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26998681/