'x << ~y'在JavaScript中代表什么?
What does 'x << ~y' represent in JavaScript?
'x << ~y'在JavaScript中代表什么?
我理解按位 SHIFT
操作是这样做的:
x << y AS x * 2y
波浪号 ~
运算符:
~x AS -(x+1)
所以,我假设如下:
5 << ~3 AS 5 * 2-4 or 5 * Math.pow(2, -4)
结果应该是 0.3125
。
但是,当我 运行 5 << ~3
结果是 1342177280
.
什么是分步说明?这种操作组合如何以及为什么会导致 1342177280
而不是 0.3125
?
(此问题类似于 Stack Overflow 问题 What are bitwise operators? 关于按位 SHIFT
运算符。)
~x
将反转 x 值的位表示(32 位有符号值和二进制补码)。
x << y
是左移运算符(这里是左移)。你的数学解释是正确的:)
您可以在此处阅读有关按位运算的更多信息:bitwise operators in Javascript
5 << ~3
给出与 5 << -4
相同的结果,你是对的。
重要的是:移动 x << y 确实会导致 x * 2y , 但它不是直接用法,它只是一个有用的副作用。
此外,如果你有一个负数 y
,它就不会以同样的方式工作。
~
运算符翻转项目的位,而 <<
是按位左移。以下是二进制中发生的事情。 注意最左边的位为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)
在最后一行中,位被移动 "rotated" 到另一边,导致一个大的正数。事实上,负数移位类似于按位旋转(溢出的位被旋转到另一侧),而正数移位没有这种行为。缺点是忽略了非旋转位。本质上意味着 5 << -4
与 5 << (32 - 4)
相同,而是旋转实际上是一个很大的偏移。
这样做的原因是因为移位只是一个 5 位 无符号 整数。因此,无符号二进制数 -4 (11100)
为 28
.
x << -n
等于 x << (32 - n)
~3 == -4
所以
5 << ~3
=== 5 << (32 - 4)
=== 5 << 28
即 1,342,177,280
to be accurate X << -n is not the same as X << (32 - n) ... in fact it's both simpler and more complicated ... the valid range of a bit shift operator is 0 to 31 ... the RHS in a bit shift operator is first converted to an unsigned 32 bit integer, then masked with 31 (hex 1f) (binary 11111
)
3 = 00000000000000000000000000000011
~3 = 11111111111111111111111111111100
0x1f (the mask) 00000000000000000000000000011111
--------------------------------
~3 & 0x1f 00000000000000000000000000011100 = 28
当星等小于32时,它和我上面发布的完全一样
位运算适用于 32 位整数。负移位没有意义,因此被包装成正 32 位整数
<< operator 的工作原理
rhs 被转换为无符号的 32 位整数 - 如此处所述ToUInt32
ToUint32 基本上取一个数字 returns 数字模 2^32
您的分析是正确的,除了您不应将 ~3 (11100)(3 (00011) 的位补码)解释为 -4 ,而是将其解释为无符号(非负)5 位整数,即 28 = 16 + 8 + 4 (11100).
这在ECMAScript standard (NB in most modern machines, positive and negative integers are represented in memory using two's complement表示中有解释:
12.8.3 左移运算符 (<<)
注意按右操作数指定的量对左操作数执行按位左移操作。
12.8.3.1 运行时语义:评估
ShiftExpression : ShiftExpression << AdditiveExpression
- 令 lref 为计算 ShiftExpression 的结果。
- 设 lval 为 GetValue(lref)。
- ReturnIfAbrupt(lval).
- 令 rref 为计算 AdditiveExpression 的结果。
- 设 rval 为 GetValue(rref)。
- ReturnIfAbrupt(rval).
- 设 lnum 为 ToInt32(lval)。
- ReturnIfAbrupt(lnum).
- 设 rnum 为 ToUint32(rval)。
- ReturnIfAbrupt(rnum)。
- 令 shiftCount 为除 rnum 的最低有效 5 位之外的所有屏蔽的结果,即计算 rnum & 0x1F。
- Return lnum 左移 shiftCount 位的结果。这
结果是一个带符号的 32 位整数。
'x << ~y'在JavaScript中代表什么?
我理解按位 SHIFT
操作是这样做的:
x << y AS x * 2y
波浪号 ~
运算符:
~x AS -(x+1)
所以,我假设如下:
5 << ~3 AS 5 * 2-4 or 5 * Math.pow(2, -4)
结果应该是 0.3125
。
但是,当我 运行 5 << ~3
结果是 1342177280
.
什么是分步说明?这种操作组合如何以及为什么会导致 1342177280
而不是 0.3125
?
(此问题类似于 Stack Overflow 问题 What are bitwise operators? 关于按位 SHIFT
运算符。)
~x
将反转 x 值的位表示(32 位有符号值和二进制补码)。
x << y
是左移运算符(这里是左移)。你的数学解释是正确的:)
您可以在此处阅读有关按位运算的更多信息:bitwise operators in Javascript
5 << ~3
给出与 5 << -4
相同的结果,你是对的。
重要的是:移动 x << y 确实会导致 x * 2y , 但它不是直接用法,它只是一个有用的副作用。
此外,如果你有一个负数 y
,它就不会以同样的方式工作。
~
运算符翻转项目的位,而 <<
是按位左移。以下是二进制中发生的事情。 注意最左边的位为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)
在最后一行中,位被移动 "rotated" 到另一边,导致一个大的正数。事实上,负数移位类似于按位旋转(溢出的位被旋转到另一侧),而正数移位没有这种行为。缺点是忽略了非旋转位。本质上意味着 5 << -4
与 5 << (32 - 4)
相同,而是旋转实际上是一个很大的偏移。
这样做的原因是因为移位只是一个 5 位 无符号 整数。因此,无符号二进制数 -4 (11100)
为 28
.
x << -n
等于 x << (32 - n)
~3 == -4
所以
5 << ~3
=== 5 << (32 - 4)
=== 5 << 28
即 1,342,177,280
to be accurate X << -n is not the same as X << (32 - n) ... in fact it's both simpler and more complicated ... the valid range of a bit shift operator is 0 to 31 ... the RHS in a bit shift operator is first converted to an unsigned 32 bit integer, then masked with 31 (hex 1f) (binary
11111
)
3 = 00000000000000000000000000000011
~3 = 11111111111111111111111111111100
0x1f (the mask) 00000000000000000000000000011111
--------------------------------
~3 & 0x1f 00000000000000000000000000011100 = 28
当星等小于32时,它和我上面发布的完全一样
位运算适用于 32 位整数。负移位没有意义,因此被包装成正 32 位整数
<< operator 的工作原理
rhs 被转换为无符号的 32 位整数 - 如此处所述ToUInt32
ToUint32 基本上取一个数字 returns 数字模 2^32
您的分析是正确的,除了您不应将 ~3 (11100)(3 (00011) 的位补码)解释为 -4 ,而是将其解释为无符号(非负)5 位整数,即 28 = 16 + 8 + 4 (11100).
这在ECMAScript standard (NB in most modern machines, positive and negative integers are represented in memory using two's complement表示中有解释:
12.8.3 左移运算符 (<<)
注意按右操作数指定的量对左操作数执行按位左移操作。
12.8.3.1 运行时语义:评估
ShiftExpression : ShiftExpression << AdditiveExpression
- 令 lref 为计算 ShiftExpression 的结果。
- 设 lval 为 GetValue(lref)。
- ReturnIfAbrupt(lval).
- 令 rref 为计算 AdditiveExpression 的结果。
- 设 rval 为 GetValue(rref)。
- ReturnIfAbrupt(rval).
- 设 lnum 为 ToInt32(lval)。
- ReturnIfAbrupt(lnum).
- 设 rnum 为 ToUint32(rval)。
- ReturnIfAbrupt(rnum)。
- 令 shiftCount 为除 rnum 的最低有效 5 位之外的所有屏蔽的结果,即计算 rnum & 0x1F。
- Return lnum 左移 shiftCount 位的结果。这 结果是一个带符号的 32 位整数。