C#位移:这个行为是在spec,bug还是偶然的?

时间:2010-02-24 14:35:53

标签: c# bit-shift

我正在使用位移操作符(请参阅我的问题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找不到任何东西),只是一个未定义行为的偶然事实,或者是否存在这种情况可能会产生错误?

1 个答案:

答案 0 :(得分:9)

我相信规范的相关部分在这里:

  

对于预定义的运算符,要移位的位数计算如下:

     
      
  • 当x的类型为int或uint时,移位计数由     低位五位计数。换句话说,计算移位计数     来自伯爵和为0x1F。

  •   
  • 当x的类型为long或ulong时,移位计数由     低位六位计数。换句话说,计算移位计数     来自伯爵和0x3F的。

  •   

如果得到的移位计数为零,则移位运算符只返回该值 x。

320x20。表达式0x20 & 0x1F的计算结果为0。因此,移位计数为零,并且不进行移位;表达式-1 << 32(或任何x << 32)只返回原始值。