6

私は JavaJava.util.Random()を JavaScript に移植するタスクを与えられましたが、Javascript で十分に大きな数値に対してビット単位の演算子を使用すると、パフォーマンスが大幅に低下したり、不正確になったりすることに遭遇しました。いくつかのざっくりとした調査では、「JavaScript のビット演算子は本質的に遅い」と述べられています。これは、内部的に JavaScript がすべての double 値を符号付き 32 ビット整数にキャストしてビット演算を実行するように見えるためです (詳細については、こちらを参照してください)。これでは、Java 乱数ジェネレーターを直接移植することはできませんJava.util.Random()。のようなものを書く

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

( Java.util.Random()Javascript はそのサイズの整数に対してビット単位の操作を実行できないため、コードは正しく動作しません)。

Lehmer アルゴリズムを使用して 32 ビット空間でシード可能な乱数ジェネレーターを作成できることがわかりましたが、秘訣は、 の場合と同じ値を取得する必要があることですJava.util.Random()。より高速で機能的な移植を行うにはどうすればよいですか?

4

4 に答える 4

4

代わりにfoo & ((1 << 48) - 1)を使用できるはずですfoo % Math.pow(2,48)

Javascript のすべての数値は 64 ビット浮動小数点数であり、48 ビット整数を表すのに十分です。

于 2010-04-04T19:11:41.823 に答える
0

JavaScript では、48 ビットのビット単位の操作はできません。ただし、2 つの数値を使用してシミュレートできます。

于 2010-04-04T19:00:11.057 に答える
0

別の方法として、48 個のブール値のブール配列を使用し、シフトを自分で実装することもできます。ただし、これがより高速かどうかはわかりません。しかし、すべてのブール値は double として格納されるため、私はそれを疑っています。

于 2010-04-04T19:03:35.280 に答える
0

ビット シフトは、2 の累乗による乗算または除算に直接相当することに注意してください。

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

これはビット シフトよりも低速ですが、32 ビットを超える拡張が可能です。より高いビット数をサポートするために必要な追加のコードを考慮すると、より高速なソリューションになる可能性がありますが、調べるにはプロファイリングを行う必要があります。bits > 32

于 2010-04-04T19:11:40.600 に答える