为什么java中的generator.nextDouble()
仅在0到1的范围内返回值? generator.nextInt()
方法要求输入限制值。为什么使用Double
方法不是这样?
答案 0 :(得分:2)
这个答案有点推测,但我想这是因为随机数生成器应该返回pseadorandom双精度统一。统一生成双打并不是微不足道的,因为双精度本身并不是均匀分布的。
忽略一般的符号,双精度或浮点数,以m * 2^e
形式存储,其中m
和e
具有固定的位宽,其中{{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);