The bit shifting operators do exactly what their name implies.
(比特移位运算符正如其名称所暗示的那样。)
They shift bits. (他们转移位。)
Here's a brief (or not-so-brief) introduction to the different shift operators. (以下是对不同班次运营商的简要介绍(或不那么简短)。)
The Operators (运营商)
-
>>
is the arithmetic (or signed) right shift operator. (>>
是算术(或签名)右移运算符。)
-
>>>
is the logical (or unsigned) right shift operator. (>>>
是逻辑(或无符号)右移运算符。)
-
<<
is the left shift operator, and meets the needs of both logical and arithmetic shifts. (<<
是左移运算符,满足逻辑和算术移位的需要。)
All of these operators can be applied to integer values ( int
, long
, possibly short
and byte
or char
).
(所有这些运算符都可以应用于整数值( int
, long
,可能是short
, byte
或char
)。)
In some languages, applying the shift operators to any datatype smaller than int
automatically resizes the operand to be an int
. (在某些语言中,将移位运算符应用于任何小于int
数据类型会自动将操作数调整为int
。)
Note that <<<
is not an operator, because it would be redundant.
(请注意<<<
不是运算符,因为它是多余的。)
Also note that C and C++ do not distinguish between the right shift operators .
(另请注意, C和C ++不区分右移运算符 。)
They provide only the >>
operator, and the right-shifting behavior is implementation defined for signed types. (它们仅提供>>
运算符,右移行为是为签名类型定义的实现。)
The rest of the answer uses the C# / Java operators. (答案的其余部分使用C#/ Java运算符。)
(In all mainstream C and C++ implementations including gcc and clang/LLVM, >>
on signed types is arithmetic. Some code assumes this, but it isn't something the standard guarantees. It's not undefined , though; the standard requires implementations to define it one way or another. However, left shifts of negative signed numbers is undefined behaviour (signed integer overflow). So unless you need arithmetic right shift, it's usually a good idea to do your bit-shifting with unsigned types.)
((在包括gcc和clang / LLVM在内的所有主流C和C ++实现中,有关签名类型的>>
是算术的。有些代码假设这一点,但它不是标准保证的东西。但它并不是未定义的 ;标准要求实现定义但是,负数有符号数的左移是未定义的行为(有符号整数溢出)。所以除非你需要算术右移,否则用无符号类型进行位移通常是一个好主意。))
Left shift (<<) (左移(<<))
Integers are stored, in memory, as a series of bits.
(整数在内存中存储为一系列位。)
For example, the number 6 stored as a 32-bit int
would be: (例如,存储为32位int
的数字6将是:)
00000000 00000000 00000000 00000110
Shifting this bit pattern to the left one position ( 6 << 1
) would result in the number 12:
(将此位模式移动到左侧一个位置( 6 << 1
)将导致数字12:)
00000000 00000000 00000000 00001100
As you can see, the digits have shifted to the left by one position, and the last digit on the right is filled with a zero.
(如您所见,数字向左移动了一个位置,右边的最后一个数字用零填充。)
You might also note that shifting left is equivalent to multiplication by powers of 2. So 6 << 1
is equivalent to 6 * 2
, and 6 << 3
is equivalent to 6 * 8
. (你可能还会注意到左移相当于乘以2的幂。所以6 << 1
相当于6 * 2
6 << 3
相当于6 * 8
。)
A good optimizing compiler will replace multiplications with shifts when possible. (一个好的优化编译器会在可能的情况下用乘法替换乘法。)
Non-circular shifting (非圆形换档)
Please note that these are not circular shifts.
(请注意,这些不是循环转换。)
Shifting this value to the left by one position ( 3,758,096,384 << 1
): (将此值向左移动一个位置( 3,758,096,384 << 1
):)
11100000 00000000 00000000 00000000
results in 3,221,225,472:
(结果为3,221,225,472:)
11000000 00000000 00000000 00000000
The digit that gets shifted "off the end" is lost.
(“失去结束”的数字将丢失。)
It does not wrap around. (它没有环绕。)
Logical right shift (>>>) (逻辑右移(>>>))
A logical right shift is the converse to the left shift.
(逻辑右移与左移相反。)
Rather than moving bits to the left, they simply move to the right. (它们不是向左移动位,而是向右移动。)
For example, shifting the number 12: (例如,移动数字12:)
00000000 00000000 00000000 00001100
to the right by one position ( 12 >>> 1
) will get back our original 6:
(向右移动一个位置( 12 >>> 1
)将取回原来的6个:)
00000000 00000000 00000000 00000110
So we see that shifting to the right is equivalent to division by powers of 2.
(所以我们看到向右移动相当于2的幂除法。)
Lost bits are gone (丢失的位消失了)
However, a shift cannot reclaim "lost" bits.
(但是,班次无法回收“丢失”的位。)
For example, if we shift this pattern: (例如,如果我们改变这种模式:)
00111000 00000000 00000000 00000110
to the left 4 positions ( 939,524,102 << 4
), we get 2,147,483,744:
(在左边4个位置( 939,524,102 << 4
),我们得到2,147,483,744:)
10000000 00000000 00000000 01100000
and then shifting back ( (939,524,102 << 4) >>> 4
) we get 134,217,734:
(然后换回( (939,524,102 << 4) >>> 4
)我们得到134,217,734:)
00001000 00000000 00000000 00000110
We cannot get back our original value once we have lost bits.
(一旦我们丢失了比特,我们就无法取回原来的价值。)
Arithmetic right shift (>>) (算术右移(>>))
The arithmetic right shift is exactly like the logical right shift, except instead of padding with zero, it pads with the most significant bit.
(算术右移与逻辑右移非常相似,除了用零填充代替填充,它填充最高有效位。)
This is because the most significant bit is the sign bit, or the bit that distinguishes positive and negative numbers. (这是因为最重要的位是符号位,或区分正数和负数的位。)
By padding with the most significant bit, the arithmetic right shift is sign-preserving. (通过使用最高有效位填充,算术右移是符号保留的。)
For example, if we interpret this bit pattern as a negative number:
(例如,如果我们将此位模式解释为负数:)
10000000 00000000 00000000 01100000
we have the number -2,147,483,552.
(我们有-2,147,483,552。)
Shifting this to the right 4 positions with the arithmetic shift (-2,147,483,552 >> 4) would give us: (用算术移位(-2,147,483,552 >> 4)将它移到右边的4个位置会给我们:)
11111000 00000000 00000000 00000110
or the number -134,217,722.
(或者数字为-134,217,722。)
So we see that we have preserved the sign of our negative numbers by using the arithmetic right shift, rather than the logical right shift.
(因此,我们看到通过使用算术右移而不是逻辑右移,我们保留了负数的符号。)
And once again, we see that we are performing division by powers of 2. (再一次,我们看到我们正以2的力量进行分裂。)