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

Dav*_*eer 5 c# bit-shift

我正在使用位移操作符(参见我的问题Bit Array Equality),SO用户在我的移位操作数计算中指出了一个错误 - 我计算的范围是[1,32]而不是[0,31]对于一个int.(为SO社区欢呼!)

在解决问题时,我惊讶地发现以下行为:

-1 << 32 == -1
Run Code Online (Sandbox Code Playgroud)

实际上,似乎n << s编译(或由CLR解释 - 我没有检查IL),n << s % bs(n)其中bs(n)= n的位数(以位为单位).

我原以为:

-1 << 32 == 0
Run Code Online (Sandbox Code Playgroud)

似乎编译器意识到你正在超越目标的大小并纠正你的错误.

这纯粹是一个学术问题,但有没有人知道这是否在规范中定义(我在7.8 Shift运算符中找不到任何东西),只是一个未定义行为的偶然事实,或者是否存在可能产生错误的情况?

Aar*_*ght 9

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

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

  • 当x的类型是int或uint时,移位计数由计数的低5位给出.换句话说,移位计数是从count&0x1F计算的.

  • 当x的类型为long或ulong时,移位计数由计数的低6位给出.换句话说,移位计数是从count&0x3F计算的.

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

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