了解class次操作员
我无法理解这个移位运算符(c#reference):
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 */
<<
是左移算子; 这将获取值的二进制表示,并将所有位“n”位置向左移动(“mod”除外,请参见“1”),用零填充。
>>
是右移运营商; 这几乎完全相反(向右移动),除了有符号值(即那些可能为负值),它为负值反向填充1,否则为0。
1:
移位运算符基本上是“修改”数据的宽度。 int是32位,因此左移33(在Int32中)与左移1完全相同。您不会得到全零。 long
是64位,因此33的左移给出不同的答案(原始时间为2 ^ 33)。
2:
每个左移(在数据宽度内)与x2相同(对于整数) - 因此<< 4是x2x2x2x2 = x16。
这是简单的二进制:
0000000001 = 1
<<去
0000000010 = 2
<<去
0000000100 = 4
<<去
0000001000 = 8
只是为了扩展Marc的答案(Marc,随意将其包括在你的内容中,我将删除这个答案)这在规范的第7.8节中有详细说明:
下面列出了预定义的移位运算符。
向左移:
- int operator <<(int x,int count);
- uint operator <<(uint x,int count);
- long运算符<<(long x,int count);
- ulong operator <<(ulong x,int count);
<<运算符将x向左移位由如下所述计算的位数。
在x的结果类型范围之外的高位被丢弃,剩余的位向左移位,并且低位空位位置被设置为零。
右移:
- int operator >>(int x,int count);
- uint operator >>(uint x,int count);
- long operator >>(long x,int count);
- ulong operator >>(ulong x,int count);
>>运算符将x向右移位如下所述计算的位数。
当x的类型为int或long时,x的低位被丢弃,其余位向右移位,如果x为非负,则高位空位位置设置为0,如果x为非负值则设置为1是消极的。
当x是uint或ulong类型时,x的低位被丢弃,其余位被右移,高位空位被设置为零。
对于预定义的运算符,要移位的位数计算如下:
当x的类型是int或uint时,移位计数由计数的低5位给出。 换句话说,移位计数是从count&0x1F计算的。
当x的类型为long或ulong时,移位计数由计数的低6位给出。 换句话说,移位计数是从count&0x3F计算的。
如果得到的移位计数为零,则移位运算符只返回x的值。
新手程序员的一些注意事项:
为何使用class次运营商? 他们似乎并没有做太多。 嗯,有两个原因:
-
它们非常快,因为几乎所有的CPU都有移位寄存器,这意味着移位操作是在硬件中完成的,只需最少的工作量(周期)。
-
因为它们很快,所以设计了许多协议和标准来利用这一点。 例如IP地址操作,检查CRC,图形操作等。
“移位运算符基本上是”修改“数据的宽度。”
垃圾! 如果移位量大于或等于数据的宽度,则结果是不确定的。 不要指望您碰巧遇到的相同’mod’操作,不同编译器或同一编译器的不同版本,或同一程序中的不同移位情况,或其他任何更改时。 这就是“未定义”的含义。