什么是'x<<~y'用JavaScript表示

What does 'x << ~y' represent in JavaScript?

本文关键字:lt 表示 JavaScript 什么      更新时间:2023-09-26

什么是'x<lt~y’在JavaScript中表示?

我知道按位SHIFT操作的作用是:

x<lt;y AS x*2y

波浪号~运算符执行以下操作:

~x AS -(x+1)

因此,我假设如下:

5<lt~3 AS 5*2-4或5*Math.pow(2,-4)

它应该导致0.3125

但是,当我运行5 << ~3时,结果是1342177280

什么是循序渐进的解释?这种操作组合是如何以及为什么产生1342177280而不是0.3125的?

(这个问题类似于Stack Overflow问题什么是位运算符?关于位SHIFT运算符。)

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

准确地说,X<lt-n与X<lt;(32-n)。。。事实上,它既简单又复杂。。。位移位运算符的有效范围是0到31。。。位移位运算符中的RHS首先转换为无符号32位整数,然后用31(十六进制1f)(二进制11111)进行掩码

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

当震级小于32时,它与我上面通过发布的内容完全相同

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

<lt;操作员操作

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

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

~运算符翻转项的位,而<<是按位左移。以下是二进制逐步发生的情况注意,最左边的位是1表示负数,这种格式是twos互补

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 << -45 << (32 - 4)是一样的,相反,旋转实际上是一个大的偏移。

这是因为位偏移只是一个5位无符号整数。因此,2中的二进制数与无符号的-4 (11100)互补将是28

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

ECMAScript标准对此进行了解释(NB在大多数现代机器中,正整数和负整数在内存中使用二的补码表示):

12.8.3左移操作员(<<)

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

12.8.1.1运行时语义:评估

ShiftExpression:ShiftExpression<lt;AdditiveExpression

  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位整数

~x将反转x值的位表示形式(32位带2补码的带符号值)。

x << y是左移操作员(此处为左)。你的数学解释是正确的:)

您可以在这里阅读更多关于位操作的信息:Javascript 中的位运算符

5 << ~3给出了与5 << -4相同的结果,您是对的。

重要事项:移位x<lt;y确实导致x*2y,但它不是直接使用,它只是一个有用的副作用
此外,如果你有一个负y,它不会以同样的方式工作。