不需要的Java bitshift行为

时间:2012-08-16 21:32:54

标签: java bit-shift

我正在为我正在进行的一些计算生成位掩码,我需要屏蔽一个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时,它实际上并不是在做什么......

1 个答案:

答案 0 :(得分:8)

是的,你是对的;在应用之前,班次由32(或64,long s)修改。

JLS 15.19

  

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

     

如果左侧操作数的提升类型很长,则只使用右侧操作数的六个最低位作为移位距离。就好像右手操作数受到按位逻辑AND运算符&amp; (§15.22.1),掩码值为0x3f(0b111111)。因此,实际使用的移位距离始终在0到63之间,包括0和63.

至于为什么 Java选择了这种行为,我对你没有任何建议。