【问题标题】:Can the result of a bitwise AND operator be negative (in Java)按位与运算符的结果可以是否为负(在 Java 中)
【发布时间】:2013-10-05 07:01:21
【问题描述】:

我有以下代码:

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

正确性 - 非负值与负值的错误比较 常量 此代码比较一个保证为 具有负常数的非负数。

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

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

【问题讨论】:

  • 你是如何声明SOME_MASK的?
  • 感谢 FindBugs 如此聪明。我经常看到按位运算符被视为“值变得未知”。

标签: java operators bit-manipulation bitwise-operators


【解决方案1】:

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

一般 - 是的。

在你的例子中 - 没有。

在 Java 中,整数以two's complement 有符号二进制表示形式表示。这种表示的一个特点是最重要的(即最左边的)位对于负数是 1,对于正数是 0。

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


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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 2012-09-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-12
            • 2019-08-03
            • 1970-01-01
            • 1970-01-01
            • 2012-01-12
            相关资源
            最近更新 更多