2012-02-17 14 views
6

En JavaScript, lo que parece:¿Por qué es JavaScript a nivel de bits O se comporta de manera extraña?

(4294958077 | 0) == -9219 

Por qué no es 4294958077?

Se sugiere que hay algún tipo de desbordamiento patadas en (aunque según entiendo rango de un tipo Número JavaScript es +/- 9007199254740992 por lo que es raro en sí mismo.)

Incluso si se trataba de un desbordamiento, sin duda

(4294958077 | 0) == 4294958077 

debe evaluar como cierto, pero no es así.

ayuda por favor

+0

Mira esto: 'alerta ((4294958077 | 0));' – Smamatti

Respuesta

5

No tiene nada que ver con el tipo de punto flotante o desbordamiento. Devuelve -9219 porque el estándar lo exige, ya que todas las operaciones binarias a nivel de bit deben realizarse usando enteros de 32 bits (ECMA-262 § 11.10).

La producción A: A @B, donde @ es uno de los operadores de bits en las producciones anteriores, se evaluó como sigue:

  1. Vamos Lref ser el resultado de evaluar A.
  2. Deje que lval sea GetValue (lref).
  3. Deje rref Sea el resultado de la evaluación B.
  4. Deje que rval sea GetValue (rref).
  5. Deje lnum sea ToInt32 (lval).
  6. Vamos rnum ser ToInt32 (rval).
  7. devolver el resultado de aplicar el operador bit a bit @ para LNUM y rnum. El resultado es un entero de 32 bits con signo.

4294958077 convierte en un entero de 32 bits con signo (utilizando el algoritmo en ECMA-262 § 9.5) es -9219, y 0 es todavía 0, por lo que el nivel de bit-o volverá -9219.

+0

+1 como se muestra por (4294958077 | 0) >>> 0 === 4294958077 no -9219 –

2

Todos los números en Javascript son números de coma flotante de 64 bits. Las operaciones a nivel de bit en flotadores son un caso marginal, por lo que internamente esos flotantes se convierten temporalmente en un int de 32 bits, luego se realiza la operación bit a bit, de ahí su desbordamiento.

0

Los números JavaScript en bit se almacenan como flotadores de 64 bits con signo, es decir, solo tiene 32 bits para usar para el entero, que ha excedido, por lo que resulta extraño convirtiéndolo en un número entero lo mejor que puede y luego haciendo la operación

Más información here (especialmente la sección 'más allá de 32 bits') pero no es una solución real, por lo que, lamentablemente, tendrá que evitarla.

Cuestiones relacionadas