operator - operadores de asignacion en javascript
¿Qué representa ''x<< ~ y'' en JavaScript? (5)
El operador
~
voltea los bits del elemento, mientras que
<<
es un desplazamiento a la izquierda bit a bit.
Esto es lo que está sucediendo en binario paso a paso.
Tenga en cuenta que el bit más a la izquierda es 1 significa un número negativo, este formato es
dos cumplidos
:
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)
En la última línea, los bits se desplazan y "giran" hacia el otro lado, lo que lleva a un gran número positivo.
De hecho, el desplazamiento por un número negativo es similar a una rotación a nivel de bits (los
bits desbordados se rotan hacia el otro lado
), donde el desplazamiento por números positivos no tiene ese comportamiento.
El inconveniente es que los bits no rotados no se tienen en cuenta.
Esencialmente significa que
5 << -4
es lo mismo que hacer
5 << (32 - 4)
, que más bien la rotación es en realidad un gran cambio.
El razonamiento para esto es porque los cambios de bits son solo un entero
sin
signo de 5 bits.
Entonces, el número binario en dos cumplidos
-4 (11100)
sin signo sería
28
.
¿Qué representa ''x << ~ y'' en JavaScript?
Entiendo que la operación
SHIFT
bitwise hace esto:
x << y AS x * 2y
Y un operador tilde
~
hace:
~x AS -(x+1)
Entonces, supongo lo siguiente:
5 << ~3 AS 5 * 2-4 or 5 * Math.pow(2, -4)
Debería resultar en
0.3125
.
Pero, cuando ejecuto
5 << ~3
resulta en
1342177280
.
¿Qué es una explicación paso a paso?
¿Cómo y por qué esta combinación de operaciones da como resultado
1342177280
en lugar de
0.3125
?
(Esta pregunta es similar a la pregunta de desbordamiento de pila ¿
Qué son los operadores bit a bit?
Sobre el operador
SHIFT
bit a bit).
Su análisis es correcto, excepto que no debe interpretar ~ 3 (11100) (el complemento de 3 (00011)) como -4, sino como un entero de 5 bits sin signo (que no es negativo), es decir 28 = 16 + 8 + 4 (11100).
Esto se explica en el estándar ECMAScript ( NB en la mayoría de las máquinas modernas, los enteros positivos y negativos se representan en la memoria usando la representación del complemento a dos ):
12.8.3 El operador de desplazamiento a la izquierda (<<)
NOTA Realiza una operación de desplazamiento a la izquierda bit a bit en el operando izquierdo por la cantidad especificada por el operando derecho.
12.8.3.1 Semántica de tiempo de ejecución: evaluación
ShiftExpression: ShiftExpression << AdditiveExpression
- Deje que lref sea el resultado de evaluar ShiftExpression.
- Deje que lval sea GetValue (lref).
- ReturnIfAbrupt (lval).
- Deje que rref sea el resultado de evaluar AdditiveExpression.
- Deje que rval sea GetValue (rref).
- ReturnIfAbrupt (rval).
- Deje que lnum sea ToInt32 (lval).
- ReturnIfAbrupt (lnum).
- Deje que rnum sea ToUint32 (rval).
- ReturnIfAbrupt (rnum).
- Deje que shiftCount sea el resultado de enmascarar todos los 5 bits menos significativos de rnum, es decir, calcular rnum & 0x1F.
- Devuelve el resultado del desplazamiento izquierdo a la izquierda por los bits shiftCount. El resultado es un entero de 32 bits con signo.
5 << ~3
da el mismo resultado que
5 << -4
, tienes razón.
Lo importante: cambiar
x << y
realmente resulta en
x * 2
y
, pero no es un uso directo, es solo un efecto secundario útil.
Además, si tiene una
y
negativa, no funciona de la misma manera.
x << -n
es igual a
x << (32 - n)
~3 == -4
entonces
5 << ~3
===
5 << (32 - 4)
===
5 << 28
que es
1,342,177,280
para ser exactos X << -n no es lo mismo que X << (32 - n) ... de hecho es más simple y más complicado ... el rango válido de un operador de desplazamiento de bits es de 0 a 31 ... el RHS en un operador de desplazamiento de bits se convierte primero a un entero de 32 bits sin signo, luego se enmascara con 31 (hexadecimal 1f) (binario
11111
)
3 = 00000000000000000000000000000011
~3 = 11111111111111111111111111111100
0x1f (the mask) 00000000000000000000000000011111
--------------------------------
~3 & 0x1f 00000000000000000000000000011100 = 28
cuando la magnitud es inferior a 32, es exactamente igual a lo que publiqué anteriormente
Las operaciones de bits funcionan con enteros de 32 bits. Los cambios de bits negativos no tienen sentido, por lo que están envueltos en enteros positivos de 32 bits
Cómo funciona el operador <<
El rhs se convierte en un entero de 32 bits sin signo, como se explica aquí ToUInt32
ToUint32 básicamente toma un número y devuelve el número módulo 2 ^ 32
~x
invertirá la representación en bits de su valor x (valor con signo de 32 bits con complemento a dos).
x << y
es el operador de desplazamiento a la izquierda (aquí a la izquierda).
Tu interpretación matemática es correcta :)
Puede leer más sobre las operaciones bit a bit aquí: operadores bit a bit en Javascript