C# 了解移位运算符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/460562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:16:15  来源:igfitidea点击:

Understand the shift operator

c#

提问by Sara S

I can not understand this shift operator (c# reference):

我无法理解这个移位运算符(c# 参考):

class MainClass1
{
 static void Main()
    {
        int i = 1;
        long lg = 1;
        Console.WriteLine("0x{0:x}", i << 1);
        Console.WriteLine("0x{0:x}", i << 33);
        Console.WriteLine("0x{0:x}", lg << 33);
    }
}

/*
Output:
0x2
0x2
0x200000000
*/

class MainClass2
{
     static void Main()
     {
         int a = 1000;
         a <<= 4;
         Console.WriteLine(a);
     }
}

/*
Output:
16000
*/

回答by Marc Gravell

<<is the left-shift operator; this takes the binary representation of a value, and moves all the bits "n" places to the left (except for "mod", see "1"), back-filling with zeros.

<<是左移运算符;这采用值的二进制表示,并将所有位“n”向左移动(“mod”除外,参见“1”),用零回填。

>>is the right-shift operator; this does nearly the opposite (moving to the right), except for signed values (i.e. those that can be negative) it back-fills with 1s for negative values, else zeros.

>>是右移运算符;这几乎相反(向右移动),除了有符号值(即那些可能为负的值),它用 1 回填负值,否则为零。

1:

1:

The shift operator is essentially "mod" the width of the data. An int is 32 bits, so a left shift of 33 (in Int32) is exactly the same as a left shift of 1. You don't get all zeros. A longis 64 bits, so a left-shift of 33 gives a different answer (original times 2^33).

移位运算符本质上是“修改”数据的宽度。int 是 32 位,因此左移 33(在 Int32 中)与左移 1 完全相同。您不会得到全零。Along是 64 位,因此左移 33 给出了不同的答案(原始时间为 2^33)。

2:

2:

Each left shift (within the data width) is the same (for integers) as x2 - so <<4 is x2x2x2x2 = x16.

每个左移(在数据宽度内)与 x2 相同(对于整数) - 所以 <<4 是 x2x2x2x2 = x16。

This is simple binary:

这是一个简单的二进制文件:

0000000001 = 1

<< goes to

<<前往

0000000010 = 2

<< goes to

<<前往

0000000100 = 4

<< goes to

<<前往

0000001000 = 8

回答by Jon Skeet

Just to expand on Marc's answer a little (Marc, feel free to include this in yours and I'll delete this answer) this is specified in section 7.8 of the spec:

只是为了稍微扩展一下 Marc 的答案(Marc,请随意将其包含在您的答案中,我将删除此答案)这在规范的第 7.8 节中指定:



The predefined shift operators are listed below.

下面列出了预定义的移位运算符。

Shift left:

左移:

  • int operator <<(int x, int count);
  • uint operator <<(uint x, int count);
  • long operator <<(long x, int count);
  • ulong operator <<(ulong x, int count);
  • int 运算符 <<(int x, int count);
  • uint 运算符 <<(uint x, int count);
  • 长运算符 <<(long x, int count);
  • ulong 运算符 <<(ulong x, int count);

The << operator shifts x left by a number of bits computed as described below.

<< 运算符将 x 左移若干位,计算如下所述。

The high-order bits outside the range of the result type of x are discarded, the remaining bits are shifted left, and the low-order empty bit positions are set to zero.

x 的结果类型范围之外的高位被丢弃,其余位左移,低位空位位置设置为零。

Shift right:

右移:

  • int operator >>(int x, int count);
  • uint operator >>(uint x, int count);
  • long operator >>(long x, int count);
  • ulong operator >>(ulong x, int count);
  • int 运算符 >>(int x, int count);
  • uint 运算符 >>(uint x, int count);
  • 长运算符 >>(long x, int count);
  • ulong 运算符 >>(ulong x, int count);

The >> operator shifts x right by a number of bits computed as described below.

>> 运算符将 x 右移若干位,计算如下所述。

When x is of type int or long, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero if x is non-negative and set to one if x is negative.

当 x 为 int 或 long 类型时,x 的低位被丢弃,其余位右移,如果 x 为非负,则高位空位位置设置为零,如果 x 设置为 1是否定的。

When x is of type uint or ulong, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero.

当 x 为 uint 或 ulong 类型时,x 的低位被丢弃,其余位右移,高位空位位置设置为零。

For the predefined operators, the number of bits to shift is computed as follows:

对于预定义的运算符,要移位的位数计算如下:

When the type of x is int or uint, the shift count is given by the low-order five bits of count. In other words, the shift count is computed from count & 0x1F.

当 x 的类型为 int 或 uint 时,移位计数由 count 的低五位给出。换句话说,移位计数是从 count & 0x1F 计算出来的。

When the type of x is long or ulong, the shift count is given by the low-order six bits of count. In other words, the shift count is computed from count & 0x3F.

当 x 的类型为 long 或 ulong 时,移位计数由 count 的低六位给出。换句话说,移位计数是从 count & 0x3F 计算出来的。

If the resulting shift count is zero, the shift operators simply return the value of x.

如果产生的移位计数为零,移位运算符只返回 x 的值。



回答by Bogdan Gavril MSFT

A few more notes for the novice programmer:

给新手程序员的一些注意事项:

Why use shift operators? They don't seem to do much. Well, there are 2 reasons:

为什么要使用移位运算符?他们似乎做的不多。嗯,有两个原因:

  1. They are really fast, because nearly all CPUs have shift registers, meaning the shifting operation is done in the hardware, in the minimum amount of effort (cycles).

  2. Because they are fast, a lot of protocols and standards are designed to take advantage of this. For example IP address operations, checking a CRC, graphic operations etc.

  1. 它们真的很快,因为几乎所有的 CPU 都有移位寄存器,这意味着移位操作是在硬件中以最少的工作量(周期)完成的。

  2. 由于它们速度很快,因此设计了许多协议和标准来利用这一点。例如 IP 地址操作、校验 CRC、图形操作等。

回答by Bogdan Gavril MSFT

"The shift operator is essentially "mod" the width of the data."

“移位运算符本质上是“修改”数据的宽度。”

Rubbish! If the amount of the shift is greater than, or equal to, the width of the data, the result is undefined. Do not expect the same 'mod' operation that you happen to have seen, to happen with different compilers, or different versions of the same compiler, or in different shift situations in the same program, or when anything else changes. That's what 'undefined' means.

垃圾!如果移位量大于或等于数据的宽度,则结果未定义。不要期望您碰巧看到的相同“mod”操作会发生在不同的编译器或同一编译器的不同版本中,或在同一程序中的不同移位情况下,或当其他任何事情发生变化时。这就是“未定义”的意思。