2012-01-28 11 views
9

En la respuesta aceptada en mi pregunta anterior (What is the fastest way to generate a random integer in javascript?), me preguntaba cómo un número pierde sus decimales a través del símbolo | .¿Cómo x | 0 planta el número en JavaScript?

Por ejemplo:

var x = 5.12042; 
x = x|0; 

¿Cómo funciona ese piso el número de 5?

Algunos ejemplos más:

console.log(104.249834 | 0); //104 
console.log(9.999999 | 0); // 9 
+2

Debe tener en cuenta que el uso de operadores bit a bit lo limitará a enteros con signo de 32 bits. '((Math.pow (2,32)/2) -1) | 0; // 2147483647' Quita el '-1' y no obtendrás el resultado deseado. '((Math.pow (2,32)/2)) | 0; // -2147483648' –

+0

Interesante. Esa es probablemente la razón por la cual esta función es ligeramente más rápida que la función 'Math.floor (x)'. http://jsperf.com/floor-or-or – user824294

+1

no es en realidad 'suelo', intente con '-1.23' para ver qué sucede – ajax333221

Respuesta

13

Debido a que, de acuerdo con las especificaciones ECMAScript, operadores operadores de bits llaman ToInt32 en cada expresión a evaluar.

Ver 11.10 Binary Bitwise Operators:

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

  1. Evaluar A.

  2. Llame GetValue(Result(1)).

  3. Evaluar B.

  4. Llame GetValue(Result(3)).

  5. llamada ToInt32(Result(2)).

  6. llamada ToInt32(Result(4)).

  7. Aplicar el operador de bits @ a Result(5) y Result(6). El resultado es un entero de 32 bits con signo.

  8. Devuelve Result(7).

5

operadores bit a bit convertir sus argumentos a números enteros (ver http://es5.github.com/#x9.5). mayoría de los lenguajes no son compatibles con este tipo de conversión:

 
    $ python -c "1.0|0" 
    Traceback (most recent call last): 
     File "", line 1, in 
    TypeError: unsupported operand type(s) for |: 'float' and 'int' 

    $ ruby -e '1.0|0' 
    -e:1:in `': undefined method `|' for 1.0:Float (NoMethodError) 

    $ echo "int main(){1.0|0;}" | gcc -xc - 
    : In function ‘main’: 
    :1: error: invalid operands to binary | (have ‘double’ and ‘int’) 

+4

' s/Most (. *?) do not/Strongly typed \ 1 generalmente no lo hacen/'(Esto es, sin embargo, muy dependiente del idioma). –

2

cuando se hace una floor, aunque sería posible convertir el argumento a un entero, esto no es lo que la mayoría de los idiomas se hacen porque el tipo de original es un número de coma flotante.

Una mejor manera de hacerlo mientras conserva el tipo de datos es ir a exponent dígitos en el mantissa y poner a cero los bits restantes.

Si le interesa, puede echar un vistazo a IEEE spec para obtener números en coma flotante.

Cuestiones relacionadas