什么是模32或64减少?

时间:2012-02-01 21:53:58

标签: java binary bit-manipulation

在Core Java Volume1一书中,有一个警告说:

  

注意:移位运算符的右侧参数以模32减少   (除非左侧是长的,在这种情况下,右侧是模64减少)。   例如,值<&lt;&lt; 35与1&lt; 1&lt; 3或8。

这究竟是什么意思?还有为什么1变为8,而不是在35左移后变为0?

非常感谢

3 个答案:

答案 0 :(得分:10)

减少模32意味着(在其基级)你保持减去32,直到你有一个0到31之间的数字。

换句话说:

actualValue = givenValue % 32;

原因它这样做是因为将32位值32位向左(或右)移位没有意义,因为总是为零(因为你在一侧移位了比特并且在另一端移动了 - 对32位值执行32次操作将导致零,无论你开始的是什么)

因此对于Java整数(32位),31是合理的限制。对于长(64位),63是合理的限制。

在您提供的示例中,1 << 35的班次值从35减少到3(从35 % 32 == 3开始)和1&lt;&lt; 3是8:

 Binary
0000 0001    (1 << 0) == 1
0000 0010    (1 << 1) == 2
0000 0100    (1 << 2) == 4
0000 1000    (1 << 3) == 8
     ||||
     |||+--- 1
     ||+---- 2
     |+----- 4
     +------ 8

答案 1 :(得分:5)

在许多编程语言中,移位超过数值数据类型的大小(对于int为32位,长为64位)未定义。另一方面,Java定义它使得(n << d)等同于(n << (d % 32)),其中n是int,(n << d)等同于(n << (d % 64))其中n 1}}很长。

因此,1 << 35相当于1 << (35 % 32),等于1 << 3 = 8

答案 2 :(得分:4)

更简洁

a << b

相同
a << (b & 31)

表示int类型。

不同之处在于-1%32为-1而-1和-1为-1。 31是31和1 << -1 == 0x80000000

此行为在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.