C# 位移位:这种行为是规范中的行为、错误还是偶然?
我正在使用位移运算符(请参阅我的问题 位数组相等),一位 SO 用户指出了我计算移位操作数时出现的错误——我计算的 int 范围是 [1,32] 而不是 [0,31]。 (SO 社区万岁!)
在解决问题时,我惊讶地发现以下行为:
-1 << 32 == -1
事实上,看起来 n << s
被编译(或由 CLR 解释——我没有检查 IL)为 n << s % bs(n)
其中 bs(n) = n 的大小(以位为单位)。
我本以为:
-1 << 32 == 0
编译器似乎意识到您正在超出目标的大小并纠正您的错误。
这纯粹是一个学术问题,但有谁知道规范中是否定义了这一点(我在 7.8 移位运算符),只是未定义行为的偶然事实,或者是否存在可能产生错误的情况?
I was working with bit shift operators (see my question Bit Array Equality) and a SO user pointed out a bug in my calculation of my shift operand--I was calculating a range of [1,32] instead of [0,31] for an int. (Hurrah for the SO community!)
In fixing the problem, I was surprised to find the following behavior:
-1 << 32 == -1
In fact, it would seem that n << s
is compiled (or interpreted by the CLR--I didn't check the IL) as n << s % bs(n)
where bs(n) = size, in bits, of n.
I would have expected:
-1 << 32 == 0
It would seem that the compiler is realizing that you are shifting beyond the size of the target and correcting your mistake.
This is purely an academic question, but does anyone know if this is defined in the spec (I could not find anything at 7.8 Shift operators), just a fortuitous fact of undefined behavior, or is there a case where this might produce a bug?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我相信规范的相关部分在这里:
如果生成的移位计数为零,则移位运算符仅返回该值
x 的。
值
32
是0x20
。表达式0x20 & 0x1F
的计算结果为0
。因此,移位计数为零,不进行移位;表达式-1 << 32
(或任何x << 32
)仅返回原始值。I believe that the relevant part of the spec is here:
If the resulting shift count is zero, the shift operators simply return the value
of x.
The value
32
is0x20
. The expression0x20 & 0x1F
evaluates to0
. Therefore, the shift count is zero, and no shift is done; the expression-1 << 32
(or anyx << 32
) just returns the original value.