我有以下代码:
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结果保证是非负的?总是这样吗?
答案 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,其中一个或两个都是正数,总是正的。要了解原因,请考虑二进制表示,以及最高位发生的情况。