在处理 C# 移位运算符时,我遇到了左移运算符的意外行为。
然后我尝试了这个简单的功能:
for (int i = 5; i >= -10; i--) {
int s = 0x10 << i;
Debug.WriteLine(i.ToString().PadLeft(3) + " " + s.ToString("x8"));
}
有了这个结果:
5 00000200
4 00000100
3 00000080
2 00000040
1 00000020
0 00000010
-1 00000000 -> 00000008 expected
-2 00000000 -> 00000004 expected
-3 00000000 -> 00000002 expected
-4 00000000 -> 00000001 expected
-5 80000000
-6 40000000
-7 20000000
-8 10000000
-9 08000000
-10 04000000
直到今天,我都期望<<
运算符可以处理第二个操作数的负值。
MSDN没有说明使用第二个操作数的负值时的行为。但 MSDN 表示,运营商只使用低 5 位 (0-31),这应该适合负值。
我也尝试了long
values: long s = 0x10L << i;
,但结果相同。
那么这里会发生什么?
编辑
如您的回答中所述,负值表示不是原因。
对于所有情况,我得到了相同的错误结果:
0x10<<-3 = 0x00000000 (wrong!)
0x10<<(int)(0xfffffffd) = 0x00000000 (wrong!)
0x10<<(0x0000001d = 0x00000000 (wrong!)
expected = 0x00000002
编辑#2
这两个之一应该是真的:
1)移位运算符是一个真正的移位运算符,所以结果应该是:
1a)0x10 << -3 = 00000002
1b)0x10 << -6 = 00000000
2) 移位运算符是一个旋转运算符,所以结果应该是:
2a) 0x10 << -3 = 00000002
(same as 1a)
2b)0x10 << -6 = 40000000
但是显示的结果既不适合 1) 也不适合 2) !!!