Findbugs警告:整数移位32 - 这是什么意思?

His*_*His 10 java findbugs bit

我正在使用Findbugs扫描第三方源代码(只是在集成到我之前要小心),并发现以下警告:

long a = b << 32 | c
Run Code Online (Sandbox Code Playgroud)

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

代码在0..31范围之外执行整数移位恒定量.这样做的结果是使用整数值的低5位来决定移位多少.这可能是不希望的,它至少令人困惑.

谁有人可以解释一下上面究竟是什么意思?

谢谢!(我是Java编程的新手)

Ras*_*ber 32

Java语言规范:

如果左侧操作数的提升类型是int,则只使用右侧操作数的五个最低位作为移位距离.就好像右手操作数受到按位逻辑AND运算符&(§15.22.1)和掩码值0x1f的影响.因此,实际使用的移位距离始终在0到31的范围内,包括0和31.

因此,如果b是int,则表达式与

long a = b | c;
Run Code Online (Sandbox Code Playgroud)

我非常怀疑是什么意思.它可能应该是

long a = ((long) b << 32) | c;
Run Code Online (Sandbox Code Playgroud)

(如果b已经很长,代码是正确的,并且FindBugs错误地认为该错误).


Jon*_*ler 5

编辑:问题几乎肯定源于'b'是'int'而不是'long'这一事实.

在C中,如果"B"是整数,而不是太长,移位通过32位左,从原始值的所有位已被删除,所以总体表达的结果将是相同的"C"你会调用未定义的行为,因此任何结果都是允许的.Java以不同的方式定义 - 正如Rasmus Faber的评论和所选答案中所述 - 并且以可以移位的最大位数为模的超长移位.[做生意似乎很奇怪; 我可能已经安排了一个包含它们的语言的例外.但是,它被明确定义,这比定义的确切更重要.]在表达式被评估时,不会发生64位的强制; 它在表达式完成并且赋值发生时发生.

对5位的引用是......有趣的.这意味着如果你向左移动,比如48,或二进制110000,它就像向左移16一样.或者,' x << n'与' x << (n % 32)' 相同.