按位AND运算符的结果可能是否定的(在Java中)

时间:2013-09-29 10:18:54

标签: java operators bit-manipulation bitwise-operators

我有以下代码:

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分析警告:

  

正确性 - 非负值与否定的不良比较   常量此代码比较保证的值   具有负常数的非负数。

对于将按位AND结果与负常数进行比较的行,会弹出警告。

我不确定为什么Bitwise AND结果保证是非负的?总是这样吗?

5 个答案:

答案 0 :(得分:3)

SOME_MASK以'0'位开头时,SOME_MASK & value的结果必须为正。

答案 1 :(得分:2)

something保证不会为负数,因为Java的签名int类型使用最高有效位进行符号,并在0中清除该位(SOME_MASK)。由于something是与该掩码进行AND运算的结果,因此它不能设置该位,因此它不能为负。

答案 2 :(得分:2)

按位-AND的结果可以是负数,例如(-1) & (-1)绝对是-1

但是,如果任一操作数是非负的,则结果也必须是非负的。这是因为在2的补码表示中,负数必须设置其第31位,而非负数必须将其第31位清零。由于&仅在两个操作数位都置位时才设置一个位,因此当且仅当两个输入均为负时,结果为负。

由于SOME_MASK = 0xffff为正数,SOME_MASK & value的结果永远不会为负数。

答案 3 :(得分:2)

  

按位AND运算符的结果是否为负(在Java中)

总的来说 - 是的。

就你的例子而言 - 编号

在Java中,整数用two's complement带符号的二进制表示法表示。这种表示的一个特征是最重要的(即最左边)位是负数的一个,而正数是零。

在您的示例中,您正在与0x0000ffff进行AND运算,即将前16位设置为零。这意味着该表达式的结果不能为负数。


相比之下,如果您与0xffff0000进行AND运算,结果可能为负数。

答案 4 :(得分:1)

两个负整数的按位AND总是负的。两个整数的按位AND,其中一个或两个都是正数,总是正的。要了解原因,请考虑二进制表示,以及最高位发生的情况。