Java如何产生一个随机数?
我知道你可以使用Java中的Math.random()生成一个从0.0到1.0的随机双精度数,但是计算机如何选择一个数字呢?计算机遵循什么代码来模拟随机性 您可以在Java类声明中找到它。这个来自Math.class:Java如何产生一个随机数?,java,random,Java,Random,我知道你可以使用Java中的Math.random()生成一个从0.0到1.0的随机双精度数,但是计算机如何选择一个数字呢?计算机遵循什么代码来模拟随机性 您可以在Java类声明中找到它。这个来自Math.class: public static double random() { return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble(); } 在Eclipse中很容易做到这一点。焦点&F3。您可以在Ja
public static double random() {
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
在Eclipse中很容易做到这一点。焦点&F3。您可以在Java类声明中找到它。这个来自Math.class:
public static double random() {
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
在Eclipse中很容易做到这一点。关注&F3。关于随机数的真相是它们不是真正的随机数。它们只是以毫秒/纳米(甚至更少)为单位计算当前时间。。。因为时间总是变化的,从不重复,所以这个值不可能是同一个值,因为“同一个原因”使得随机数成为随机数 查看@FranciscoSpaeth答案:
关于随机数的真相是它们不是真正的随机数。它们只是以毫秒/纳米(甚至更少)为单位计算当前时间。。。因为时间总是变化的,从不重复,所以这个值不可能是同一个值,因为“同一个原因”使得随机数成为随机数 查看@FranciscoSpaeth答案:
通过查看文档很容易找到,因为令人高兴的是,行为在Java中定义良好。从 当第一次调用此方法时,它会创建一个新的伪随机数生成器,就像表达式一样
new java.util.Random()
遗憾的是,它没有明确说明它调用Random
上的哪个方法。但是,由于其返回值与它在“另请参阅”部分中链接的Random.nextDouble
在同一范围内,因此应该安全地假设使用的是该值
看着
在哪里
随机数生成器的种子[被初始化为]一个很可能不同于此构造函数的任何其他调用的值
通过观察这一点,应该很清楚,事实上,这个数字并不像大多数人所理解的那样是“随机的”。这是一个完全可预测的数学模式,被称为,它对于许多目的来说都是随机的。但是,根据您希望结果的不可预测性,它可能值得研究(这会产生不可预测的、加密性强的随机值)。这很容易通过查看文档找到,因为令人高兴的是,行为在Java中定义良好。从 当第一次调用此方法时,它会创建一个新的伪随机数生成器,就像表达式一样
new java.util.Random()
遗憾的是,它没有明确说明它调用Random
上的哪个方法。但是,由于其返回值与它在“另请参阅”部分中链接的Random.nextDouble
在同一范围内,因此应该安全地假设使用的是该值
看着
在哪里
随机数生成器的种子[被初始化为]一个很可能不同于此构造函数的任何其他调用的值
通过观察这一点,应该很清楚,事实上,这个数字并不像大多数人所理解的那样是“随机的”。这是一个完全可预测的数学模式,被称为,它对于许多目的来说都是随机的。但是,根据您希望结果的不可预测性,它可能值得研究(这会产生不可预测的加密强随机值)。通过查看java中random类的源代码,您会发现这取决于您是否使用种子,即调用public random()或调用public random()(长种子) 来自Java Random类的源代码:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 1181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012L);
您可以看到,如果不指定种子,则类Random将使用原子长种子并使用System.nanoTime()执行按位异或操作(^)
但是,如果确实指定了种子,则会调用代码的另一部分,而不调用System.nanoTime()
(请注意,如果在没有种子的情况下调用,则使用种子的构造函数将被称为nontheless,但其种子由System.nanoTime()组成,这保证了每次调用都有不同的种子)
首先通过调用initialScramble(长种子)方法对种子进行加扰
通过nextBytes、nextLong、nextInt等从代码中调用,调用next(),其实现如下:
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;
您可以测试带种子和不带种子的调用之间的差异。如果提供种子并仅调用一次方法nextInt、nextBytes等,则每次都将获得相同的值。
但是,如果不指定种子,即使只调用一次方法nextInt、nextBytes等,也会得到不同的值。通过查看java中Random类的源代码,您会发现这取决于是否使用种子,即调用public Random()或调用public Random(长种子) 来自Java Random类的源代码:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 1181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012L);
您可以看到,如果不指定种子,则类Random将使用原子长种子并使用System.nanoTime()执行按位异或操作(^)
但是,如果确实指定了种子,则会调用代码的另一部分,而不调用System.nanoTime()
(请注意,如果在没有种子的情况下调用,则使用种子的构造函数将被称为nontheless,但其种子由System.nanoTime()组成,这保证了每次调用都有不同的种子)
首先通过调用initialScramble(长种子)方法对种子进行加扰
通过nextBytes、nextLong、nextInt等从代码中调用,调用next(),其实现如下:
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;
您可以测试带有和不带种子的调用之间的差异