【问题标题】:What does 'x << ~y' represent in JavaScript?'x << ~y' 在 JavaScript 中代表什么?
【发布时间】:2015-12-18 05:59:39
【问题描述】:

'x

我知道按位 SHIFT 操作是这样做的:

x y

波浪号 ~ 运算符会:

~x AS -(x+1)

所以,我假设如下:

5 -4 或 5 * Math.pow(2, -4)

应该是0.3125

但是,当我运行 5 &lt;&lt; ~3 时,结果是 1342177280

什么是分步说明?这种操作组合如何以及为什么会导致1342177280 而不是0.3125

(这个问题类似于 Stack 溢出问题 What are bitwise operators? 关于按位 SHIFT 运算符。)

【问题讨论】:

  • 位移操作怎么能得到像 0.3125 这样的小数结果?
  • !--&lt;&lt;~ 之后的下一步是什么?我应该发布“^&lt;&lt;!~ 操作员做什么?”
  • @Zaibis !~--this[](...[this[$]],_=&gt;..._)
  • @Zaibis 您可能只是将左移与右移互换并再次问这个问题。您可能会获得 20 票。
  • @JonnyHenly:改变左移和右移......但是......那将是......&gt;&gt;~看起来像一个人......他能做什么。 ...我觉得我有责任问 SO“Guy 接线员是做什么的?” x'D

标签: javascript bitwise-operators


【解决方案1】:

x &lt;&lt; -n 等于 x &lt;&lt; (32 - n)
~3 == -4 所以
5 &lt;&lt; ~3 === 5 &lt;&lt; (32 - 4) === 5 &lt;&lt; 281,342,177,280

准确地说 X 11111) 屏蔽

                   3 = 00000000000000000000000000000011  
                  ~3 = 11111111111111111111111111111100
       0x1f (the mask) 00000000000000000000000000011111
                       --------------------------------
            ~3 & 0x1f  00000000000000000000000000011100 = 28

当震级小于32时,和我上面贴的完全一样

位运算适用于 32 位整数。负位移是没有意义的,所以被包装成正的 32 位整数

<< operator 的工作原理

rhs 被转换为无符号 32 位整数 - 就像这里解释的 ToUInt32

ToUint32 基本上接受一个数字并以 2^32 为模返回数字

【讨论】:

  • 如何得到-n 等于(32 - n) 的引用?我并不怀疑这就是答案。但是,我只是好奇,因为我找不到。
  • @choz 这实际上可以追溯到计算机体系结构。这是因为大多数计算机指令集使用 5 位来存储移位量(至少对于 MIPS)。特别是这些位是无符号二进制。
  • 不是 32-n。它只使用最不重要的 5 位,即n &amp; 31(请参阅有关运算符 n 为负数,则 32+n == n &amp; 31
  • @choz ... -n modulo X = X - n when abs(n) &lt;= X ... 这对我来说过于简单了
  • 如果 +3 是(二进制) ....0011 则如果这是 ....1101 而不是 ....1100 的二进制补码,其中省略号将最高有效位向左延伸需要。哎呀!此评论是多余的或不正确的或两者兼而有之,但我无法删除它,对不起
【解决方案2】:

~ 运算符翻转项目的位,而&lt;&lt; 是按位左移。这是二进制逐步发生的事情。 请注意,最左边的位为 1 表示负数,此格式为twos compliment

3         // (00000000000000000000000000000011 => +3 in decimal)
// ~ flips the bits
~3        // (11111111111111111111111111111100 => -4 in decimal)
// The number 5 (..00101) shifted by left by -4 (-4 unsigned -> 28)
5         // (00000000000000000000000000000101 => +5 in decimal)
5 << -4   // (01010000000000000000000000000000 => +1342177280 in decimal)

在最后一行中,位被移位并“旋转”到另一侧,导致一个很大的正数。事实上,负数移位类似于按位旋转(溢出的位被旋转到另一边),其中正数移位没有这种行为。缺点是未旋转的位被忽略。本质上意味着5 &lt;&lt; -45 &lt;&lt; (32 - 4) 相同,而是轮换实际上是一个很大的转变。

这样做的原因是因为位移位只是一个 5 位 无符号 整数。所以二进制complement-4 (11100) unsigned 将是28

【讨论】:

  • @JaromandaX 啊,你说得对,它是二进制 5 移位了 -4。给我一秒钟,这解释了我好像差了 1 点。
  • 感谢您的回答斯宾塞。我正在使用000001111111111111111111111111110x07FFFFFF 的在线二进制转换器,结果为134217727。我在这里做错了吗?
  • @choz 这对我来说是一团糟,我以错误的顺序阅读了最后一个表达式,偶然得到了一个非常接近的数字。我已经更新了我的答案。
  • 可能添加免责声明或仅供参考,javascript 将数字从 64 位双精度浮点数转换为 32 位整数,进行位操作,然后转换回来。很好的答案,现在它已经修复了。
  • @SpencerWieczorek 我想知道5 &lt;&lt; -45 的二进制文件正确移动了4 次,对吗?那不是说它应该等于5 &gt;&gt; 4吗?我对转移这个 bs 有点困惑.. :(
【解决方案3】:

您的分析是正确的,除了您不应将 ~3 (11100) (3 (00011) 的位补码)解释为 -4 ,而是作为无符号(即非负)5位整数,即 28 = 16 + 8 + 4 (11100)。

这在ECMAScript standard 中有解释(NB 在大多数现代机器中,正整数和负整数在内存中使用two's complement 表示):

12.8.3 左移运算符 (

注意 对左操作数按右操作数指定的量执行按位左移操作。

12.8.3.1 运行时语义:评估

ShiftExpression : ShiftExpression

  1. 设 lref 为计算 ShiftExpression 的结果。
  2. 令 lval 为 GetValue(lref)。
  3. ReturnIfAbrupt(lval)。
  4. 设 rref 为 AdditiveExpression 的计算结果。
  5. 令 rval 为 GetValue(rref)。
  6. ReturnIfAbrupt(rval)。
  7. 令 lnum 为 ToInt32(lval)。
  8. ReturnIfAbrupt(lnum)。
  9. 设 rnum 为 ToUint32(rval)。
  10. ReturnIfAbrupt(rnum)。
  11. 令 shiftCount 为屏蔽掉除 rnum 的最低有效 5 位之外的所有结果,即计算 rnum & 0x1F。
  12. 返回将 lnum 左移 shiftCount 位的结果。这 结果是一个带符号的 32 位整数。

【讨论】:

    【解决方案4】:

    ~x 将反转 x 值的位表示(带二进制补码的 32 位有符号值)。

    x &lt;&lt; y 是左移运算符(此处为左)。你的数学解释是正确的:)

    您可以在此处阅读有关按位运算的更多信息:bitwise operators in Javascript

    【讨论】:

      【解决方案5】:

      5 &lt;&lt; ~3 给出的结果与5 &lt;&lt; -4 相同,你是对的。

      重要的一点:把x 确实变成x * 2y,但这不是直接用法,而是只是一个有用的副作用。
      此外,如果你有一个否定的y,它就不会以同样的方式工作。

      【讨论】:

      • btw 应该如何处理负值?对不起,我不太了解任何东西的位表示。
      • ,如果你有一个否定的 y,它就不会以同样的方式工作所以你实际上并没有对实际问题的答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      相关资源
      最近更新 更多