按位AND运算符的结果是否可以为负(在Java中)
我有以下代码:
int SOME_MASK = 0x0000ffff;
int value = /* some value */;
int something = SOME_MASK & value;
// WHY IS "something" guaranteed to be non-negative ?
if (something != NEGATIVE_CONSTANT) {
// do something here....
}
我一直收到FindBugs分析警告:
Correctness - Bad comparison of nonnegative value with negative constant This code compares a value that is guaranteed to be non-negative with a negative constant.
将按位AND结果与负常量进行比较的行会弹出警告
我不知道为什么按位AND的结果一定是非负的?总是这样吗
# 1 楼答案
当
SOME_MASK
以“0”位开头时,SOME_MASK & value
的结果必须为正# 2 楼答案
按位AND的结果可以是负数,例如
(-1) & (-1)
肯定是-1
但是,如果任一操作数为非负,则结果也必须为非负。这是因为在2的补码表示法中,负数必须设置其第31位,而非负数必须清除其第31位。由于
&
仅当两个操作数的位都已设置时才会设置位,因此当且仅当两个输入都为负时,结果为负因为
SOME_MASK = 0xffff
是阳性的,所以SOME_MASK & value
的结果永远不会是阴性的# 3 楼答案
something
保证不为负,因为Java的有符号int
类型使用最高有效位作为符号,并且该位在SOME_MASK
中被清除(0
)。因为something
是用该掩码与某物进行AND运算的结果,所以不能设置该位,所以不能为负# 4 楼答案
总的来说——是的
在你的例子中——不
在Java中,整数用two's complement符号二进制表示。这种表示法的一个特点是,最高有效位(即最左边)是负数的1位,正数的0位
在您的示例中,您正在与
0x0000ffff
进行ANDing,这就是将前16位设置为零。这意味着表达式的结果不能是负数相比之下,如果你用
0xffff0000
进行AND运算,的结果可能是阴性的# 5 楼答案
两个负整数的位和总是负的。两个整数的按位与,其中一个或两个都是正的,总是正的。要了解原因,请考虑二进制表示,以及最高位会发生什么