2016-05-30 88 views
0

我正在實現我自己的隨機數生成器,並且我使用的算法自然給了我一個nextLong()方法。但是,使用這種核心方法,我需要實現其他標準方法,如nextLong(long),nextInt(),nextDouble()等等,就nextLong()而言。例如:使用隨機長生成隨機雙打

public long nextLong(long n) { 
    long bits, val; 
    do { 
     bits = (nextLong() << 1) >>> 1; 
     val = bits % n; 
    } while (bits - val + n - 1 < 0L); 
    return val; 
} 

public int nextInt() { 
    return (int)nextLong(); 
} 

我該如何執行nextDouble

回答

3

不知道是什麼做自己的目的,但你可以只是做同樣的方式內置Random類會爲nextDouble(),如javadoc的描述:

的方法nextDoubleRandom類實現彷彿:

public double nextDouble() { 
    return (((long)next(26) << 27) + next(27)) 
    /(double)(1L << 53); 
} 

既然你沒有一個int next(int bits)方法,但是你有一個nextLong()滿足請使用((long)next(26) << 27) + next(27)相當於next(53)的事實。由於next(int)方法返回int,即完成了很長的一步, 32位。

從長得到53位,你可以使用低或高53位,您的選擇:

long low53 = nextLong() & ((1L << 53) - 1); 
long high53 = nextLong() >>> (64 - 53); 

所以,你的代碼是:

private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0/(1L << 53) 
public double nextDouble() { 
    return (nextLong() >>> (64 - 53)) * DOUBLE_UNIT; 
} 

DOUBLE_UNIT東西Random實際上是如何在內部執行的,因爲乘法比分割更快,例如見Floating point division vs floating point multiplication

+0

我自己做這件事的目的是實現一個**可逆**隨機數發生器,它實現了歷史和方法來對發生器的狀態進行反向和前進步進。我研究了繼承'Random'來做到這一點,但它似乎只是通過重寫'next'來嘗試添加所有這些功能。因此,單獨的類。 –

+0

'((long)next(26)<< 27)+ next(27)'在邏輯上與'next(53)'相同,只不過'Random'中的next()方法返回int即最大32位。 'next(53)'與'nextLong()&((1L << 53) - 1)'或'nextLong()>>>(64 - 53)'相同,取決​​於你想要低還是高長的53位。 – Andreas