这更多的是语言设计而不是编程问题.
以下是JLS 15.19移位运算符的摘录:
如果左手操作数的提升类型是
int,则只使用右手操作数的五个最低位作为移位距离.如果左侧操作数的提升类型是
long,则只使用右侧操作数的六个最低位作为移位距离.
这种行为也在C#中指定,虽然我不确定它是否在Javascript的官方规范中(如果有的话),但至少基于我自己的测试也是如此.
结果是以下情况属实:
(1 << 32) == 1
Run Code Online (Sandbox Code Playgroud)
据我所知,这个规范很可能受到以下事实的启发:当移位32位值(64位为6位)时,底层硬件只占用计数操作数的5位,我可以理解在例如,JVM级别,但为什么高级语言(如C#和Java)会保留这种相当低级别的行为?它们不应该提供超出硬件实现的更抽象的视图,并且行为更直观吗?(如果他们可以采取负数来表示向其他方向转移,那就更好了!)
有人可以解释为什么以下按位表达式返回不同的结果:
System.out.println((-1<<31)<<1); // it prints 0
System.out.println(-1<<32); // it prints -1
Run Code Online (Sandbox Code Playgroud) 可能重复:
为什么1 >> 32 == 1?
-1作为转换为二进制的int由32 1表示.当我右移31次时,我得到1(31 0和1).但当我右移32次时,我再次得到-1.它不应该等于0吗?
我知道>>(比两倍大)正在转移,但究竟>>>做了什么?
System.out.println(16>>>2); // OK
System.out.println(8>>>2); // OK
System.out.println(8>>>2); // OK
System.out.println(8<<<2); // not OK
Run Code Online (Sandbox Code Playgroud) 我有两个相关的问题:
按位运算符>>>表示我们正在将二进制数转移多个位置,同时在最高位填充0.但是,为什么以下操作产生相同的数字:5 >>> 32产生5和-5 >>> 32产生-5.因为如果上面的描述是正确的,那么这两个操作都会产生0作为最终结果.
在上面的继续中,根据Effective Java book,我们应该在计算哈希码时使用(int)(f ^(f >>> 32))(如果字段很长)(如果字段很长).为什么我们这样做,解释是什么