2010-04-04 25 views
6

Se me ha asignado la tarea de portar el código Java.util.Random() de Java a JavaScript, y me he encontrado con un gran impacto de rendimiento/inexactitud usando operadores bit a bit en Javascript en números suficientemente grandes. Algunas investigaciones someras afirman que "los operadores bit a bit en JavaScript son intrínsecamente lentos", porque internamente parece que JavaScript va a convertir todos sus valores dobles en enteros de 32 bits para realizar las operaciones bit a bit (see here para obtener más información al respecto). , No puedo hacer un puerto directo del generador de números aleatorios de Java, y necesito obtener los mismos resultados numéricos que Java.util.Random(). Escribir algo así comooperaciones bit a bit de 48 bits en Javascript?

this.next = function(bits) { 
    if (!bits) { 
     bits = 48; 
    } 
    this.seed = (this.seed * 25214903917 + 11) & ((1 << 48) - 1); 
    return this.seed >>> (48 - bits); 
    }; 

(que es un puerto de casi directa de la Java.util.Random()) código no funcionará correctamente, ya que Javascript no puede hacer operaciones bit a bit en un número entero de ese tamaño.)

I' he descubierto que puedo crear un generador de números aleatorios en un espacio de 32 bits con el algoritmo de Lehmer, pero el truco es que necesito obtener los mismos valores que con Java.util.Random(). ¿Qué debo hacer para hacer un puerto más rápido y funcional?

Respuesta

0

Las operaciones bit a bit de 48 bits no son posibles en JavaScript. Sin embargo, podría usar dos números para simularlo.

0

Una alternativa es usar una matriz booleana de 48 booleanos e implementar el cambio usted mismo. No sé si esto es más rápido, sin embargo; pero lo dudo, ya que todos los booleanos se almacenan como dobles.

0

tener en cuenta que un desplazamiento de bits es directamente equivalente a una multiplicación o división por una potencia de 2.

1 << x == 1 * Math.pow(2,x) 

Es más lento que desplazamiento de bits, pero le permite extender más allá de 32 bits. Es puede ser una solución más rápida para bits > 32, una vez que tenga en cuenta el código adicional que necesita para admitir un mayor número de bits, pero tendrá que hacer algunos perfiles para averiguarlo.

4

En lugar de foo & ((1 << 48) - 1) debe poder usar foo % Math.pow(2,48).

Todos los números en Javascript son números de punto flotante de 64 bits, que es suficiente para representar cualquier entero de 48 bits.

Cuestiones relacionadas