seb*_*ebf 2 c# bit-manipulation
我在我的C#应用程序中有一个方法试图打包一个整数,但是移位运算符表现得很奇怪.
下面代码中的注释显示了执行行后调试器看到的代码内容.
long code = 0; //0x0000000000000000
code += (0x1111 << 32); //0x0000000000001111
code += (0x2222 << 16); //0x0000000022221111
code += (0x3333); //0x0000000022224444
Run Code Online (Sandbox Code Playgroud)
从第一行开始,我预计括号中包含的代码将首先被执行,这将导致0x1111向左移位32位,但它不是,但在下一行,移位确实发生,并且也是正确的位置(即在添加之前必须移位0x2222,否则结果将为0x33330000).
有什么我错过了解释这个的操作员?
什么,你错过的是在该整数位的移位操作国防部32由于0x1111是int,该操作是0x1111 << (32 % 32),这是0x1111 << 0,这仅仅是0x1111.
你可能想要的是什么0x1111L << 32.
从C#规范的第7.9节:
当x的类型是
int或时uint,移位计数由低位五位给出count.换句话说,移位计数是从count & 0x1F.当x的类型是
long或时ulong,移位计数由低位6位给出count.换句话说,移位计数是从count & 0x3F.
在某些硬件体系结构上,将int转换为32将产生0,而其他体系结构将产生相同的int.为了保持一致的行为,C#的设计者必须选择其中一个选项.当前行为只需要& 0x1F对体系结构上的移位计数执行,否则会产生0.然而,总是返回0将需要比较和产生int的体系结构上的分支.由于分支机构往往价格昂贵,因此在大多数情况下选择最快的选项是有道理的.