在Java中我有一個隨機生成器,生成從-2^63到2^63的隨機數,這不是java.util.Random。從隨機長生成隨機數
我需要生成的(0,1)隨機雙,這是我迄今所做的:
return (seed/(double)(9223372036854775807L))/2+0.5;//seed is a random long
這是正確的?有沒有數字問題(下溢?)?
可能會更好/更快?
謝謝。
在Java中我有一個隨機生成器,生成從-2^63到2^63的隨機數,這不是java.util.Random。從隨機長生成隨機數
我需要生成的(0,1)隨機雙,這是我迄今所做的:
return (seed/(double)(9223372036854775807L))/2+0.5;//seed is a random long
這是正確的?有沒有數字問題(下溢?)?
可能會更好/更快?
謝謝。
我會用Math.scalb作爲最有效,並確保有沒有搞笑的行爲,由於四捨五入或表示錯誤
double d = Math.scalb(seed >>> 1, -63);
只能在雙所以一些將被丟棄使用53位。
如果運行
long seed = Long.MAX_VALUE;
System.out.println(Math.scalb(seed >>> 1, -63));
打印
0.5
爲0的種子,你得到0.0
隨着-1你得到1.0
用此: double d = Math.scalb(seed >>> 1,63); return d + 0.5; 我得到這些數字: 7.60172909551165E27 | 2.6062896340692396E35 | 4.0765687952289006E36 –
對不起,得到了錯誤的方式。你可以'返回d;' –
惠特這個種子-7545188140698174557 我得到這個數字1.1819490194320679(它大於1)。 –
不完全。我認爲更簡單的方法是做到以下幾點: new Random(seed).nextDouble()
我沒有使用Java隨機。 –
@FabioF。但是你沒有說過你不能。 ;) –
我寧願只看到一個部門。
0.5+(seed/1.84467440737096E+19);
這就是說,你要對問題進行浮點精確度,因爲你有64個隨機整數位,然後嘗試擠進雙精度53位跑起來。您可能更適合爲浮點值製作專用的發生器,但我無法確定,因爲我不知道您的動機。
我需要一個很長的時間,通常發生器用於隨機長期,但我也應該實現雙隨機。 –
除非我誤讀了需要從0到1的隨機double,否則Java內置的Math.random就是這樣做的。所以你可以避免你目前正在進行的所有轉換。
的最快方式種子可能只是將您的前三位設置爲0
然後使用那些位,使雙:
double rand = Double.longBitsToDouble(seed & 0x1FFFFFFFFFFFFFFFL);
這是通過迫使符號爲正,而指數比0少,這將導致尾數是正確的至少一次移動。假設long中的所有整數都是完全隨機的,它會得到均勻的分佈。下面是一個使用隨機生成隨機渴望一個完整的Java程序,則此方法將它們轉換爲0和1之間翻一番的:
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之間的均勻分佈,因爲有更多的小雙打,你可能永遠都不會看到接近的條數1.您可以通過生成新的expone解決這個問題NT基於現有一個的位,但你需要一個循環做到這一點,所以它可能不是最快的方法在保理這個後:
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.819287 0898479095
0.9365016017283178
0.11311614413193898
嗡嗡聲,我刪除了評論..現在的數字在範圍內和隨機..但非常接近零..我應該做更多的測試! :) –
@FabioF。嗯,這是均勻隨機分配**所有**可能的兩倍,介於0和1之間,但由於有更多可能的小雙打,它在這個意義上分配不均勻。 – Paulpro
Whao,這是輝煌和可怕的..無論如何,我是大於1(1.3484676232953214,惠特這個長9223048428104072362)。 –
可以擺脫'/ 2'和摺疊說成'種子/ xxx'部分 –
沒有,那將是太偉大了,是一個漫長的。 –
做一個雙 –