5

我正在使用位移运算符(请参阅我的问题Bit Array Equality)并且一个 SO 用户指出了我计算移位操作数时的一个错误——我计算的范围是 [1,32] 而不是 [0,31]一个整数。(为 SO 社区欢呼!)

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

-1 << 32 == -1

事实上,它似乎n << s被编译(或由 CLR 解释——我没有检查 IL),n << s % bs(n)其中 bs(n) = n 的大小,以位为单位。

我本来期望:

-1 << 32 == 0

编译器似乎意识到您正在超出目标的大小并纠正您的错误。

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

4

1 回答 1

9

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

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

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

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

如果结果移位计数为零,则移位运算符简单地返回 x 的值。

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

于 2010-02-24T14:40:36.890 回答