Java 7随机类

时间:2016-12-21 18:05:38

标签: java

为什么java中的generator.nextDouble()仅在0到1的范围内返回值? generator.nextInt()方法要求输入限制值。为什么使用Double方法不是这样?

4 个答案:

答案 0 :(得分:2)

这个答案有点推测,但我想这是因为随机数生成器应该返回pseadorandom双精度统一。统一生成双打并不是微不足道的,因为双精度本身并不是均匀分布的。

忽略一般的符号,双精度或浮点数,以m * 2^e形式存储,其中me具有固定的位宽,其中{{1} }被解释为m(包括)和0之间的数字(不包括)。这意味着对于高数字,两个连续双打之间的差异远大于小数字。因此,简单地用随机位填充双精度将不会产生均匀分布的伪随机数。

相反,解决方法是将指数1固定为0,并且只选择一个随机尾数e,它会产生0到1之间均匀分布的双精度。如果你需要一个不同的随机双精度数范围,您可以将数字乘以所需范围:

m

当范围不是太高时,这在实践中会很好。

答案 1 :(得分:2)

从概念的角度来看,人们可以争辩说0.0和1.0之间的区间在数学意义上是很好的:在给定0.0到0.0之间的随机数的情况下计算任意范围内的随机数是微不足道的。 1.0。当然,可以在Random类中插入实用程序方法,同样简单的实现:

public double nextDouble(double min, double max) {
    return min + nextDouble() * (max - min);
}

现在可以问为什么这样的方法首先不是基本的实现。也就是说,为什么应该基于现有的nextDouble()方法实现此方法,以及为什么没有方法可以直接生成所需范围内的值"。

Hoopje in his answer已经指出了一个重要的观点:原因可能是0.0和1.0之间的范围更适合表示均匀分布的值

在查看(或者更确切地说:仔细阅读)有关IEEE 754 floating point number format的详细信息时,您会看到值变大时值的密度会减少。

当你启动IEEE calculator并输入0.0,1.0和1.70141 * 10 ^ 38的值时,你会看到它们的表示(对于float这里 - 该声明类似地适用于{ {1}}):

double

事实上,0.0到1.0之间的浮点数基本上与1.0和170141163178059628080016879768630000000.0之间的相同。实现一个好的,统一的随机数生成器并不简单,考虑到可表示值 selfself 不均匀分布的问题,创建任意范围的专用实现是不可能的。

因此,对于0.0到1.0的范围,可以生成值均匀分布的实体语句。对于其他范围,人们必须争论什么"均匀性"实际上应该意味着某个范围...

答案 2 :(得分:1)

我带你去询问API设计的动机。这有点推测,但选择设计的至少一个好理由是它很容易正确实现,同时仍然可以提供任意大小的随机数(因为你可以扩展结果)。

另一个原因可能是nextDouble()的结果范围遵循了浮点PRNG的长期惯例。

我很欣赏您发现整数和浮点API之间的区别令人不安,但它绝不是Java(和其他)整数和FP API之间的唯一区别。这两种数值表示用于完全不同的目的,很少相交。强迫他们拥有类似的API是没有什么好处的。

答案 3 :(得分:0)

你可以简单地用这个成语来实现你想要做的事情:

double max = 100000; // just an example
double randomDouble = (new Random()).nextDouble() * max;

理论上,我认为没有充分的理由说明他们无法提供 这样的方法如下。我认为这不仅仅是因为 上面的成语很简单,没有人抱怨: - )

/**
 * Return a pseudorandom, uniformly distributed double value between
 * 0 (inclusive) and the specified <code>max</code> value (exclusive)
 * drawn from this random number generator's sequence.
 * @param max
 * @return
 */
double nextDouble(double max);