位移位运算符完全正如它们的名字所暗示的。它们移位。这里有一个简短的(或不那么简单)介绍不同的班次操作符。
操作符
>>>是算术(或有符号)右移运算符。
>>>>>是逻辑(或无符号)右移位运算符。
><
所有这些运算符都可以应用于整数值(int,long,可能为短整型和字节或char)。在某些语言中,将shift运算符应用于小于int的任何数据类型会自动将操作数的大小调整为int。
注意,<>运算符,并且移位行为是实现定义的。
左移(<
整数在存储器中存储为一系列位。例如,存储为32位int的数字6将是:
00000000 00000000 00000000 00000110
将该位模式移位到左一个位置(6 <<1)将导致数字12:
00000000 00000000 00000000 00001100
正如你所看到的,数字向左移动一个位置,右边的最后一个数字用零填充。你也可能注意到左移相当于乘以2的幂。因此6<< 1等于6 * 2,并且6 < 3相当于6 * 8.一个好的优化编译器将尽可能地用移位替换乘法。
非圆形移位
请注意,这不是循环移位。将该值向左移动一个位置(3,758,096,384 <1):
11100000 00000000 00000000 00000000
结果3,221,225,472:
11000000 00000000 00000000 00000000
被移动“离开结束”的数字丢失。它不环绕。
逻辑右移(>>>)
逻辑右移是与左移相反。而不是将位移动到左边,他们只是向右移动。例如,移动数字12:
00000000 00000000 00000000 00001100
向右移动一个位置(12>>>> 1)将得到我们原来的6:
00000000 00000000 00000000 00000110
所以我们看到向右移动等效于除以2的幂。
丢失的位消失了
然而,移位不能回收“丢失”位。例如,如果我们改变这种模式:
00111000 00000000 00000000 00000110
到左边的4个位置(939,524,102 <4),我们得到2,147,483,744:
10000000 00000000 00000000 01100000
然后移回((939,524,102 4)> 4),我们得到134,217,734:
00001000 00000000 00000000 00000110
一旦丢失了位,我们就无法找回我们的原始值。
算术右移(>>)
算术右移准确地类似于逻辑右移,除了代替用零填充,它用最高有效位填充。这是因为最高有效位是符号位,或区分正数和负数的位。通过用最高有效位填充,算术右移是符号保留。
例如,如果我们将此位模式解释为负数:
10000000 00000000 00000000 01100000
我们有-2,147,483,552。将其移动到具有算术移位(-2,147,483,552>> 4)的右侧4个位置将给出:
11111000 00000000 00000000 00000110
或数字-134,217,722。
所以我们看到,我们使用算术右移,而不是逻辑右移,保留了负数的符号。再次,我们看到我们以2的权力执行分裂。