dyk*_*ykw 5 java bit-manipulation bit-shift
我有使用Java的这种行为:
int b=16;
System.out.println(b<<30);
System.out.println(b<<31);
System.out.println(b<<32);
System.out.println(b<<33);
Run Code Online (Sandbox Code Playgroud)
输出:0 0 16 32
java位移位循环吗?如果没有,为什么我在b << 30和16时b <32时得到0?
rge*_*man 12
位移不是循环的; 对于位移ints,Java仅使用5个最低有效位,因此(b << 0)相当于(b << 32)(相当于(b << 64)等).您可以简单地取位移量并在除以32时取余数.
对于位移longs 也会出现类似情况,其中Java仅使用6个最低有效位,因此(aLong << 0)相当于(aLong << 64).
JLS第15.19节谈到了这一点:
如果左侧操作数的提升类型是int,则只使用右侧操作数的五个最低位作为移位距离.就好像右手操作数受到按位逻辑AND运算符&(§15.22.1)和掩码值0x1f(0b11111)的影响.因此,实际使用的移位距离始终在0到31的范围内,包括0和31.
如果左侧操作数的提升类型很长,则只使用右侧操作数的六个最低位作为移位距离.就好像右手操作数受到按位逻辑AND运算符&(§15.22.1)和掩码值0x3f(0b111111)的影响.因此,实际使用的移位距离始终在0到63的范围内,包括0和63.
(强调我的)
(你不能对floats或doubles进行比特移位,并且尝试按比例移位a short或者a byte会使值一直受到一元数字提升的影响int.)
你0来自16 << 30,因为1位来自16
00000000 00000000 00000000 00010000
Run Code Online (Sandbox Code Playgroud)
从最后移开int并被丢弃.
// Discarded - Result-----------------------------
(00000100) 00000000 00000000 00000000 00000000
Run Code Online (Sandbox Code Playgroud)
不,这不是循环转变.这是正常的左移.只是,对于int类型左侧操作数,Java仅使用右操作数的5个低位来进行移位.这符合JLS§15.9:
如果左侧操作数的提升类型是int,则只使用右侧操作数的五个最低位作为移位距离.就好像右手操作数受到按位逻辑AND运算符&(§15.22.1)和掩码值0x1f(0b11111)的影响.因此,实际使用的移位距离始终在0到31的范围内,包括0和31
因此,对于16 << 32仅考虑5个低阶位32,表达式相当于:
16 << 32 & 0x1f
Run Code Online (Sandbox Code Playgroud)
等于16.
| 归档时间: |
|
| 查看次数: |
912 次 |
| 最近记录: |