我正在使用位移操作符(参见我的问题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运算符中找不到任何东西),只是一个未定义行为的偶然事实,或者是否存在可能产生错误的情况?
我相信规范的相关部分在这里:
对于预定义的运算符,要移位的位数计算如下:
当x的类型是int或uint时,移位计数由计数的低5位给出.换句话说,移位计数是从count&0x1F计算的.
当x的类型为long或ulong时,移位计数由计数的低6位给出.换句话说,移位计数是从count&0x3F计算的.
如果得到的移位计数为零,则移位运算符只返回x的值.
价值32是0x20.表达式的0x20 & 0x1F计算结果为0.因此,移位计数为零,并且不进行移位; 表达式-1 << 32(或任何x << 32)只返回原始值.