おそらく最速の方法は、longの最初の3ビットをに設定し、0
それらのビットを使用してdoubleを作成することです。
double rand = Double.longBitsToDouble(seed & 0x1FFFFFFFFFFFFFFFL);
これは、符号を正に強制し、指数を0未満にすることで機能します。これにより、仮数が少なくとも1回右にシフトされます。long内のすべてのintが完全にランダムであると仮定すると、均等な分布が得られます。これは、Randomを使用してランダムなlongを生成し、次にこのメソッドを使用してそれらを0から1までのdoubleに変換する完全なJavaプログラムです。
import java.util.Random;
class Main{
public static void main(String[] args){
Random rand = new Random();
long seed = rand.nextLong();
double x = Double.longBitsToDouble(seed & 0x1FFFFFFFFFFFFFFFL);
System.out.println(x);
}
}
これは、10回の実行の出力です。
1.1211565592484309E-247
8.84224349357039E-242
6.956043405745214E-271
3.747746366809532E-232
9.302628573486166E-158
1.1440116527034282E-166
1.2574577719255876E-198
5.104999671234867E-269
3.360619724894072E-213
1.5654452507283312E-220
編集
これにより、0から1までのすべての可能なdoubleが均一に分散されます。小さいdoubleが多数あるため、1に近い数値が表示されることはほとんどありません。これは、既存の指数のビットに基づいて新しい指数を生成することで修正できます。しかし、それを行うにはループが必要なので、これを考慮した後、おそらく最速の方法ではありません。
long exponent = 0;
for(int i = 52; (seed >>> i & 1) > 0; i++) exponent++;
double x = Double.longBitsToDouble(seed & 0x000FFFFFFFFFFFFFL | ((1022 - exponent) << 52));
0.4773960377161338
0.929045618651037
0.7183096209363845
0.33962049395497845
0.45568660174922454
0.11670190555677815
0.09371618427480996
0.8192870898479095
0.9365016017283178
0.11311614413193898