对JAVA程序员来说,我们都知道java.lang.Math类中有一个random的静态方法来生成随机数。这个方法生成一个double的随即数,这个数的范围在(0.0,1.0)之间,通过乘上某个数来完成0至某个数之间的随机数。
可是对于随即数如何产生的,到底这个数是不是真的随即你知道多少呢?
一、随机数的产生
我们拿源码说话
public static double random() {
if (randomNumberGenerator == null) initRNG();
return randomNumberGenerator.nextDouble();
}
这里需要一个随即数的生成器
private static synchronized void initRNG() {
if (randomNumberGenerator == null)
randomNumberGenerator = new Random();
}
其实随机数生成器只是一个叫Random()类
private final AtomicLong seed;
private final static long multiplier = 0x5DEECE66DL;
private final static long mask = (1L << 48) - 1;
private static volatile long seedUniquifier = 8682522807148012L;
public Random() { this(++seedUniquifier + System.nanoTime()); }
public Random(long seed) {
this.seed = new AtomicLong(0L);
setSeed(seed);
}
synchronized public void setSeed(long seed) {
seed = (seed ^ multiplier) & mask;
this.seed.set(seed);
haveNextNextGaussian = false;
}
这就是几乎所有相关源码了
经过这一些计算之后就能得到所谓的随即数了。二、为什么随机数随即至于为什么计算之后就是随即数了,我也一直抱有怀疑的看法。我看源码注释上看到了如下说明
An instance of this class is used to generate a stream of
pseudorandom numbers.
意思说这个是生成一个伪随机数的类。
三、随机数和伪随机数? 维基百科上如下说明
产生随机数有多种不同的方法。这些方法被称为随机数发生器。随机数最重要的特性是它在产生时后面
的那个数与前面的那个数毫无关系。
真正的随机数是使用物理现象产生的:比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等等。
这样的随机数发生器叫做物理性随机数发生器,它们的缺点是技术要求比较高。
在实际应用中往往使用伪随机数就足够了。这些数列是“似乎”随机的数,实际上它们是通过一个
固定的、可以重复的计算方法产生的。它们不真正地随机,因为它们实际上是可以计算出来的,
但是它们具有类似于随机数的统计特征。这样的发生器叫做伪随机数发生器。