【问题标题】:Different between bitwise left shift of Int32 and Int64 [closed]Int32和Int64的按位左移之间的区别[关闭]
【发布时间】:2021-08-18 11:20:14
【问题描述】:

代码:

var test1 = 1 & Int64.Parse("1") << 32; // 0
var test2 = 1 & Int32.Parse("1") << 32; // 1 <= It should be 0

您好,有人可以帮我理解上图的结果吗?为什么结果不一样。 我们有这方面的教程吗?

【问题讨论】:

  • 试试1 &amp; Int64.Parse("1") &lt;&lt; 64;。它也会导致 1。我很确定它溢出了。
  • 因为只有两行,所以我将您的代码添加为文本,OP。请始终将代码添加为文本(如有必要,请添加图片用于说明目的),否则我们无法调试它。
  • 您期望什么结果,为什么?我在 cmets 中看到您希望 1 作为 64 位的 LSB?如果将1 向左移动 32 次然后屏蔽 LSB,64 位会发生什么?
  • Here 是“教程”。
  • /* 1 after shift 32 bit = 00000000 00000000 00000000 00000000 * 32 bit/ // operator &amp; with 1 /* 1 = 00000000 00000000 00000000 00000001 * 32 bit/ 我预计结果应该是 0。因为 1 在向左移动 32 位后变为 0。

标签: c# binary


【解决方案1】:

Lower down the same page that @KekuSemau references

移位运算符的移位计数

对于移位运算符 &lt;&lt;&gt;&gt;,右侧操作数的类型必须是 int 或具有预定义的隐式数字转换为 int 的类型。

对于x &lt;&lt; countx &gt;&gt; count 表达式,实际移位计数取决于x 的类型,如下所示:

  • 如果x 的类型为intuint,则移位计数由右侧操作数的低五位定义。也就是说,移位计数是根据count &amp; 0x1F(或count &amp; 0b_1_1111)计算得出的。

  • 如果x 的类型是longulong,则移位计数由右侧操作数的低六位定义。也就是说,移位计数是根据count &amp; 0x3F(或count &amp; 0b_11_1111)计算得出的。

换句话说,任何高于值中位数的移位都将被简单地丢弃。

这反映在 C# 规范 ECMA-334 Part 12.10 中,该规范还添加了:

如果结果移位计数为零,移位运算符只返回 x 的值。

移位操作永远不会导致溢出,并且在检查和未检查的上下文中产生相同的结果。

【讨论】:

    【解决方案2】:

    来自msdn:
    The left-shift operation discards the high-order bits that are outside the range of the result type and sets the low-order empty bit positions to zero

    溢出的位放回另一边。
    照这样说,对于 Int32,任何 lshift >= 32 都应该导致 0,但事实并非如此。

    似乎&lt;&lt;n 执行为&lt;&lt; (n % bitsize)
    这意味着对于 Int32:

    查看 Linqpad 中的 IL,我可以看到 &lt;&lt; 66
    IL_0008: ldc.i4.2
    IL_0009: shl
    ...它直接执行&lt;&lt;2

    【讨论】:

      猜你喜欢
      • 2018-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-03
      • 2013-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多