2009-06-21 55 views
8

我被扫描使用了findBUGs第三方源代码(只是为了整合到它矿之前谨慎),并且发现以下警告:Findbugs警告:整数偏移32 - 这是什么意思?

long a = b << 32 | c 

错误:整数移位通过32模式ID: ICAST_BAD_SHIFT_AMOUNT ,类型:BSHIFT, 类别:正确性

代码执行由 恒定量 0..31的范围外的整数偏移。这样做的效果是使用整数值 的低5位来决定移动多少。这 可能是不是想要的,并且 它至少混淆。

请问谁能解释一下上面的含义呢?

谢谢! (我在Java编程相当新手)

回答

30

Java Language Specification

如果左边的操作数的提升的类型为int,只有右边的操作数的五个最低阶位被用作移位距离。就好像右侧的操作数受掩码值0x1f的按位逻辑AND运算符&(第15.22.1节)的处理。实际使用的换档距离总是在0到31的范围内。

所以,如果b是int,则表达式是相同的

long a = b | c; 

我强烈怀疑是何意。它应该可能是

long a = ((long) b << 32) | c; 

(如果b已经很长,代码是正确的,FindBugs会误解这个错误)。

5

编辑:这个问题几乎可以肯定的事实,“B”是一个“廉政”,而不是“长”茎。

在C语言中,如果'b'是一个整数而不是一个long,并且您向左移动了32位,原始值的所有位都被移除了,所以整体表达式的结果将与'c'你会调用未定义的行为,所以任何结果都是允许的。 Java对事物的定义有所不同 - 正如Rasmus Faber的评论和所选答案中所述 - 并且以可移动的最大位数为模来进行超长移位。 [这似乎是一种奇怪的做生意的方式;我可能已经安排了一个有他们的语言的例外。但是,它是明确定义的,这比定义更为重要。]在评估表达式时,不会发生对64位的强制性处理;它发生在表达式完成并且分配发生时。

对5位的引用是...耐人寻味。这意味着如果您向左移动48或二进制110000,则与向左移动16相同。或者,'x << n'与'x << (n % 32)'相同。

+1

D'oh,你是对的,删除我的答案,并upmodded你的:) – 2009-06-21 07:41:02

+1

你的答案的第一部分是不正确的。在Jave中,b << 32是b,而不是零。然而,第二个paragraåh是正确的。 – 2009-06-21 07:45:09

相关问题