什么是按位偏移(位移位),运营商和它们如何工作? [英] What are bitwise shift (bit-shift) operators and how do they work?

查看:799
本文介绍了什么是按位偏移(位移位),运营商和它们如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图学习C在我的业余时间,和其他语言(C#,Java等)有相同的概念(通常在同一运营商)...

I've been attempting to learn C in my spare time, and other languages (C#, Java, etc.) have the same concept (and often the same operators) ...

我想知道的,在核心层,这是什么位移(LT;&LT ;, >>,>>>)做的,它可以帮助什么问题解决,和周围的弯曲潜伏的陷阱是什么?换句话说,一个绝对的初学者指南位转移在其所有的善良。

What I'm wondering is, at a core level, what does bit-shifting (<<, >>, >>>) do, what problems can it help solve, and what gotchas lurk around the bend? In other words, an absolute beginner's guide to bit shifting in all its goodness.

推荐答案

位转移运营商做的正是顾名思义。他们移位位。这里有一个简单的(或不那么简单)介绍了不同的移位运算符。

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.


  • &GT;方式&gt; 的算术(或签字)向右移位运算符

  • &GT;&GT;&GT; 是逻辑(或符号)右移位运算。

  • &LT;&LT; 是左移位运算符,符合逻辑和算术移位的需求

  • >> 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.

所有这些操作符可以应用到整数值( INT ,可能字节字符)。在某些语言,运用转移运营商的任何数据类型比 INT 小自动调整操作数是一个 INT

All of these operators can be applied to integer values (int, long, possibly short and byte or char). In some languages, applying the shift operators to any datatype smaller than int automatically resizes the operand to be an int.

注意&LT;&LT;&LT; 不是一个运营商,因为这将是多余的。还要注意的是C和C ++不右移运营商之间distingiush。他们只提供&GT;&GT; 运营商,并定义换挡行为实施

Note that <<< is not an operator, because it would be redundant. Also note that C and C++ do not distingiush between the right shift operators. They provide only the >> operator, and the shifting behavior is implementation defined.

整数被存储在存储器中的一系列位。例如,6号保存为一个32位的 INT 是:

Integers are stored, in memory, as a series of bits. For example, the number 6 stored as a 32-bit int would be:

00000000 00000000 00000000 00000110

这换挡位模式向左一个位置( 6≤;&LT; 1 )将导致12号:

00000000 00000000 00000000 00001100

正如可以看到的,数字都向左移动一个位置,并且在右边的最后一位数字被填充以零。你可能也注意到,左移相当于提高2所以 6≤权力的乘法;&LT; 1 等同于 6 * 2 6≤;&LT; 3 等同于 6 * 8 。一个好的优化编译器将取代变化可能乘法时。

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. A good optimizing compiler will replace multiplications with shifts when possible.

请注意,这些是的的循环变化。一个位置这个值向左移( 3758096384&LT;&LT; 1

Please note that these are not circular shifts. Shifting this value to the left by one position (3,758,096,384 << 1):

11100000 00000000 00000000 00000000

结果3221225472:

results in 3,221,225,472:

11000000 00000000 00000000 00000000

这被转向关底的数字将丢失。它不回绕。

The digit that gets shifted "off the end" is lost. It does not wrap around.

一个逻辑右移是相反的左移。而不是移动位到左侧,他们只需移动到右侧。例如,移动数字12:

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:

00000000 00000000 00000000 00001100

由一个立场的权利( 12 GT;&GT;&GT; 1 )将回到我们原来的6:

to the right by one position (12 >>> 1) will get back our original 6:

00000000 00000000 00000000 00000110

因此​​,我们看到,向右移由2。权力相当于除法

So we see that shifting to the right is equivalent to division by powers of 2.

然而,移位无法收回丢失位。例如,如果我们转向这种模式:

However, a shift cannot reclaim "lost" bits. For example, if we shift this pattern:

00111000 00000000 00000000 00000110

向左4个职位( 939524102&LT;&4; ),我们得到2147483744:

to the left 4 positions (939,524,102 << 4), we get 2,147,483,744:

10000000 00000000 00000000 01100000

然后再移回((939524102&LT;&4;)&GT;&GT;&GT; 4 ),我们得到134217734:

and then shifting back ((939,524,102 << 4) >>> 4) we get 134,217,734:

00001000 00000000 00000000 00000110

我们不能回到我们原来的价值,一旦我们失去了位。

We cannot get back our original value once we have lost bits.

的算术右移是完全一样的逻辑右移,除了代替填充的零,它具有最显著位垫。这是因为最显著位是符号的位,或区分正数和负数位。通过与最显著位填充,算术右移是先签后换preserving。

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.

例如,如果我们间preT这位模式为负数:

For example, if we interpret this bit pattern as a negative number:

10000000 00000000 00000000 01100000

我们拥有数-2,147,483,552。这个转移到右侧4个位置的算术移位(-2,147,483,552 >> 4)会给我们:

we have the number -2,147,483,552. Shifting this to the right 4 positions with the arithmetic shift (-2,147,483,552 >> 4) would give us:

11111000 00000000 00000000 00000110

或数-134,217,722

or the number -134,217,722.

所以我们看到,我们有$ P $使用算术右移,而不是逻辑右移pserved我们负数的符号。再一次,我们看到,我们被2的幂进行划分。

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.

这篇关于什么是按位偏移(位移位),运营商和它们如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆