我正在为我正在进行的一些计算生成位掩码,我需要屏蔽一个int,除了x最右边的位以外都是零。我是这样做的:
int mask = ~(-1 << x);
这适用于x的所有值,除了x = 32.它应该返回-1然后,但它返回0.这里发生了什么?
另外,我试过这个:
int mask = -1 >>> 32 - x;
在x = 0时它应该返回0,但它返回-1。以某种方式将某些东西移动32会导致操作返回操作员的左侧。当我尝试将-1移位33或34位时,它返回一个值,好像它移动了1或2.我是否正确假设Java实际上是这样的:
int mask = ~(-1 << x % 32);
和
int mask = -1 >>> (32 - x) % 32;
如果是这样的话,如果超过int的32位长度,为什么还要这个循环行为呢?关于Oracle的文档明确指出:
无符号右移运算符“&gt;&gt;&gt;”将零转换为 最左边的位置
但显然,当它必须移动超过32时,它实际上并不是在做什么......
答案 0 :(得分:8)
是的,你是对的;在应用之前,班次由32(或64,long
s)修改。
如果左侧操作数的提升类型为int,则只使用右侧操作数的五个最低位作为移位距离。就好像右手操作数受到按位逻辑AND运算符&amp; (§15.22.1),掩码值为0x1f(0b11111)。因此,实际使用的移动距离始终在0到31的范围内,包括0和31。
如果左侧操作数的提升类型很长,则只使用右侧操作数的六个最低位作为移位距离。就好像右手操作数受到按位逻辑AND运算符&amp; (§15.22.1),掩码值为0x3f(0b111111)。因此,实际使用的移位距离始终在0到63之间,包括0和63.
至于为什么 Java选择了这种行为,我对你没有任何建议。