JavaScript中的'x <<〜y'代表什么?

JavaScript中的'x <<〜y'代表什么?

我明白,按位SHIFT操作这样做:

  x << y AS x * 2 y 

而波浪号~操作符可以:

 ~x AS -(x+1) 

所以,我假设如下:

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

它应该导致0.3125

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

什么是一步一步的解释? 如何以及为什么这个操作组合会导致1342177280而不是0.3125

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

x << -n等于x << (32 - n)
~3 == -4等等
5 << ~3 1,342,177,280 === 5 << 281,342,177,280 5 << (32 - 4) === 5 << 28这就是1,342,177,280

准确X << -n与X <<(32-n)不一样…实际上它更简单也更复杂…位移运算符的有效范围是0到31 …位移运算符中的RHS首先被转换为无符号的32位整数,然后用31(hex1f)(二进制11111

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

当幅度小于32时,与我上面发表的完全一样

位操作使用32位整数。 负位移是毫无意义的,所以被包裹成正32位整数

<<运算符如何工作

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

ToUint32基本上是一个数字,并返回模数2 ^ 32的数字

~操作符翻转项的位,而<<是左移位。 这里是二进制发生的一步一步。 请注意,最左边的位是1表示一个负数,这种格式是赞美

 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 << -4与做5 << (32 - 4) ,相当于旋转实际上是一个大转变。

其原因是因为位移只是一个5位无符号整数。 所以二进制数字二进制表示恭维-4 (11100)无符号将是28

你的分析是正确的,除了你不应该把〜3(11100)(3(00011)的位互补)解释为-4,而是作为一个无符号(也就是非负)的5位整数,即28 = 16 + 8 + 4(11100)。

这在ECMAScript标准中得到了解释(在大多数现代机器中,正负整数在内存中使用二进制补码来表示):

12.8.3左移运算符(<<)

注意对左侧操作数执行按位右移操作,操作数由右侧操作数指定。

12.8.3.1运行时语义:评估

ShiftExpression:ShiftExpression << 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是除了最低有效5位的rnum之外的所有结果,即计算rnum&0x1F。
  12. 通过shiftCount位返回左移lnum的结果。 结果是一个有符号的32位整数。

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

x << y是左移运算符(这里是左)。 你的math解释是正确的:)

您可以在这里阅读更多关于按位运算的内容: Javascript中的按位运算符

5 << ~3给出的结果与5 << -4相同,你说得对。

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