2010-04-04 23 views
6

Mi è stato affidato il compito di eseguire il porting di Java Java.util.Random() in JavaScript e ho riscontrato un enorme successo/inaccuratezza delle prestazioni utilizzando operatori bit a bit in Javascript su numeri sufficientemente grandi. Alcune ricerche sommarie affermano che "gli operatori bit a bit in JavaScript sono intrinsecamente lenti", perché internamente sembra che JavaScript trasmetterà tutti i suoi doppi valori in numeri interi a 32 bit con segno per eseguire operazioni bit a bit (see here per ulteriori informazioni su questo.) A causa di questo , Non posso fare una porta diretta del generatore di numeri casuali Java, e ho bisogno di ottenere gli stessi risultati numerici come Java.util.Random(). Scrivendo qualcosa comeOperazioni bit a bit a 48 bit in Javascript?

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

(che è una porta quasi-diretta del Java.util.Random()) codice non funzionerà correttamente, dal momento che Javascript non può fare operazioni bit per bit su un numero intero di quelle dimensioni.)

I' Ho capito che posso semplicemente creare un generatore di numeri casuali seedable nello spazio a 32 bit usando l'algoritmo Lehmer, ma il trucco è che ho bisogno di ottenere gli stessi valori come con Java.util.Random(). Cosa devo fare per realizzare una porta più veloce e funzionale?

risposta

0

Le operazioni bit a bit a 48 bit non sono possibili in JavaScript. Potresti usare due numeri per simularlo però.

0

Un'alternativa consiste nell'utilizzare un array booleano di 48 booleani e implementare lo spostamento da soli. Non so se questo è più veloce, però; ma ne dubito, dal momento che tutti i booleani sono memorizzati come doppi.

0

tenga presente che uno spostamento bit è direttamente equivalente ad una moltiplicazione o divisione per una potenza di 2.

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

è più lento di bit spostamento, ma consente di estendere oltre 32 bit. È maggio essere una soluzione più veloce per bits > 32, una volta che si fattore nel codice aggiuntivo è necessario supportare un numero maggiore di conteggi di bit, ma si dovrà fare qualche profilazione per scoprirlo.

4

Invece di foo & ((1 << 48) - 1) dovresti essere in grado di utilizzare foo % Math.pow(2,48).

Tutti i numeri in Javascript sono numeri in virgola mobile a 64 bit, che è sufficiente per rappresentare qualsiasi numero intero a 48 bit.