以下代码中按位运算符奇怪行为的原因是什么?

时间:2012-03-27 12:48:05

标签: c# bit-manipulation

我的C#应用​​程序中有一个方法试图打包一个整数,但是移位运算符表现得很奇怪。
下面代码中的注释显示了执行行后调试器看到的代码内容。

        long code = 0;          //0x0000000000000000
        code += (0x1111 << 32); //0x0000000000001111
        code += (0x2222 << 16); //0x0000000022221111
        code += (0x3333);       //0x0000000022224444

从第一行开始,我希望括号中包含的代码将首先被执行,这将导致0x1111向左移位32位,但它不是,但在下一行,转移确实发生,并且在正确的位置(即在添加之前必须移位0x2222,否则结果将是0x33330000)。

对于解释此问题的运营商,我有什么遗漏?

2 个答案:

答案 0 :(得分:6)

你错过的是对int的位移操作是mod 32.由于0x1111int,操作是0x1111 << (32 % 32),即0x1111 << 0,这是只是0x1111

您可能想要的是0x1111L << 32

来自C#规范的第7.9节:

  
      
  • 当x的类型为intuint时,移位计数由count的低位5位给出。换句话说,班次计数是从count & 0x1F计算的。

  •   
  • 当x的类型为longulong时,移位计数由count的低位6位给出。换句话说,班次计数是从count & 0x3F计算的。

  •   

在某些硬件架构上,将int移位32将产生0,而其他架构将产生相同的int。为了保持一致的行为,C#的设计者必须选择其中一个选项。当前行为只需要对体系结构上的移位计数执行& 0x1F,否则会产生0.然而,总是返回0将需要比较和产生int的体系结构上的分支。由于分支往往价格昂贵,因此在大多数情况下选择最快的选项是有道理的。

答案 1 :(得分:1)

我相信它是因为0x1111被视为int