C# 位移位:这种行为是规范中的行为、错误还是偶然?

发布于 2024-08-23 12:20:25 字数 657 浏览 4 评论 0原文

我正在使用位移运算符(请参阅我的问题 位数组相等),一位 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

删除会话 2024-08-30 12:20:25

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

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

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

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

如果生成的移位计数为零,则移位运算符仅返回该值
x 的。

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

I believe that the relevant part of the spec is here:

For the predefined operators, the number of bits to shift is computed as follows:

  • When the type of x is int or uint, the shift count is given by the
    low-order five bits of count. In other words, the shift count is computed
    from count & 0x1F.

  • When the type of x is long or ulong, the shift count is given by the
    low-order six bits of count. In other words, the shift count is computed
    from count & 0x3F.

If the resulting shift count is zero, the shift operators simply return the value
of x.

The value 32 is 0x20. The expression 0x20 & 0x1F evaluates to 0. Therefore, the shift count is zero, and no shift is done; the expression -1 << 32 (or any x << 32) just returns the original value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文