我正在使用位移操作符(请参阅我的问题Bit Array Equality)并且SO用户在我的移位操作数计算中指出了一个错误 - 我正在计算[1,32]的范围而不是[0,31]对于int。 (为SO社区欢呼!)
在解决问题时,我惊讶地发现以下行为:
-1 << 32 == -1
事实上,似乎n << s
被编译(或由CLR解释 - 我没有检查IL)为n << s % bs(n)
,其中bs(n)= size,以位为单位, of。
我原以为:
-1 << 32 == 0
似乎编译器意识到你正在超越目标的大小并纠正你的错误。
这纯粹是一个学术问题,但有没有人知道这是否在规范中定义(我在7.8 Shift operators找不到任何东西),只是一个未定义行为的偶然事实,或者是否存在这种情况可能会产生错误?
答案 0 :(得分:9)
我相信规范的相关部分在这里:
对于预定义的运算符,要移位的位数计算如下:
当x的类型为int或uint时,移位计数由 低位五位计数。换句话说,计算移位计数 来自伯爵和为0x1F。
当x的类型为long或ulong时,移位计数由 低位六位计数。换句话说,计算移位计数 来自伯爵和0x3F的。
如果得到的移位计数为零,则移位运算符只返回该值 x。
值32
为0x20
。表达式0x20 & 0x1F
的计算结果为0
。因此,移位计数为零,并且不进行移位;表达式-1 << 32
(或任何x << 32
)只返回原始值。