0

我有以下代码:

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

正确性 - 非负值与负常数的错误比较 此代码将保证为非负的值与负常数进行比较。

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

我不确定为什么按位与结果保证为非负数?总是这样吗?

4

5 回答 5

3

SOME_MASK以“0”位开始时,结果SOME_MASK & value必须为正。

于 2013-09-29T10:21:59.977 回答
2

something保证不会是负数,因为 Java 的有符号int类型使用符号的最高有效位,并且该位0SOME_MASK. 由于something是与该掩码进行“与”运算的结果,因此不能设置该位,因此不能为负。

于 2013-09-29T10:22:08.753 回答
2

按位与的结果可以是负数,例如(-1) & (-1)肯定是-1

但是,如果任一操作数为非负数,则结果也必须为非负数。这是因为在 2 的补码表示中,负数的第 31 位必须置位,非负数的第 31 位必须清零。因为&只有在设置了两个操作数的位时才会设置一个位,所以当且仅当两个输入都为负时,结果才为负。

既然SOME_MASK = 0xffff是正数,结果SOME_MASK & value就永远不会是负数。

于 2013-09-29T10:22:39.770 回答
2

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

一般来说 - 是的。

在你的例子中 - 不。

在 Java 中,整数以二进制补码符号表示。这种表示的一个特征是最高有效位(即最左边)对于负数是一,对于正数是零。

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


相比之下,如果您与 进行 AND 运算0xffff0000,结果可能是否定的。

于 2013-09-29T10:46:44.113 回答
1

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

于 2013-09-29T10:22:26.270 回答