Java的随机数原理
Java生成隨機數(shù)時,可以會使用以下方法
final int i = new Random().nextInt(int bound);
或者
final double v = Math.random();
初一看,以為是兩種方式,其實第二種的底層也是使用了Random的方法nextDouble(),所以我們主要看Random的方法即可。
原理
計算機生成隨機數(shù),有幾種方式
1.物理方式
正在意義上的隨機數(shù)生成器,無法預測且無周期,一般利用計算機的電阻、熱噪聲等得到隨機數(shù),不過物理方式生成隨機數(shù)的效率不高,需要計算機高效的計算。
2.隨機數(shù)表方式
事先生成好隨機數(shù),放在內(nèi)存里,需要時從表里獲取,這種需要內(nèi)存,如果隨機數(shù)量非常大,那將需要很大的內(nèi)存。
3.偽隨機數(shù)方式
使用“種子”來生成隨機數(shù)序列,使用算法在種子基礎上生成隨機數(shù),由于是算法生成的,偽隨機數(shù)生成是可以預測且周期性的,并不算是真正意義上的隨機,所以叫偽隨機數(shù)。
同余法
同余公式(congruential formula)是一種常用的偽隨機數(shù)算法。在Java中,線性同余算法就是同余算法的一種變種。Random類中,使用了48(bit)位作為種子,在線性同余算法中生成隨機數(shù)。
使得結果小于某個數(shù),一般使用取余的計算,結果都是同一除數(shù)的余數(shù),所以叫做同余法。
nextInt(int bound)方法會返回一個偽隨機的,均勻分布于0(包含)到bound(不包含)之間的int值。
其中next(int bit)方法源碼
protected int next(int bits) {long oldseed, nextseed;AtomicLong seed = this.seed;do {oldseed = seed.get();nextseed = (oldseed * multiplier + addend) & mask;} while (!seed.compareAndSet(oldseed, nextseed));return (int)(nextseed >>> (48 - bits));}線性同余公式就是這一行代碼,
nextseed = (oldseed * multiplier + addend) & mask;
這個和以下線性公式非常相似
Xn+1=(a*Xn+c)(mod m)
Xn剛開始時就是初始化時的“種子”,經(jīng)過運算會得到新的“種子”nextseed作為下一次運算的“種子”oldseed。
或許,你覺得疑惑求余,沒看到有取余的計算,可以看看multiplier,addend,mask變量
和mask(即是 (1L << 48) - 1)作與運算,就是取余的運算。
總結
以上是生活随笔為你收集整理的Java的随机数原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一文速读阿里云ET大脑 ——阿里云机器智
- 下一篇: json文件转xml