首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 7随机类

Java 7随机类
EN

Stack Overflow用户
提问于 2016-12-21 18:05:37
回答 4查看 151关注 0票数 4

为什么java中的generator.nextDouble()只返回0到1之间的值?generator.nextInt()方法要求输入一个限值。为什么Double方法不是这样呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-12-21 19:05:40

这个答案有点推测,但我想原因是随机数生成器应该是均匀地返回pseadorandom。均匀地产生双值一点也不简单,因为加倍本身并不是均匀分布的。

忽略符号、双数或浮点数通常都存储在表单m * 2^e中,其中me有固定的位宽,m被解释为0 (包括)和1 (独占)之间的数字。这意味着,对于高数字,连续两个双打之间的差异远远大于小数字。因此,简单地用随机比特填充双比特不会产生均匀分布的伪随机数。

相反,解决方案是将指数e固定为0,并且只选择一个随机尾数m,该值在0到1之间产生一个均匀分布的双倍。如果需要在不同的范围内随机加倍,则可以将该数字乘以所需的范围:

代码语言:javascript
复制
double randomDouble = rng.nextDouble() * range;

当射程不太高时,这在实践中就足够好了。

票数 2
EN

Stack Overflow用户

发布于 2016-12-21 19:31:47

从概念的角度来看,人们可能会争辩说,从数学意义上讲,0.0到1.0之间的间隔是很好的:给定0.0到1.0之间的随机数,在任意范围内计算一个随机数是很简单的。当然,可以在Random类中插入实用程序方法,实现也同样简单:

代码语言:javascript
复制
public double nextDouble(double min, double max) {
    return min + nextDouble() * (max - min);
}

现在人们可能会问,为什么这样的方法一开始就不是基本的实现。也就是说,为什么应该基于现有的nextDouble()方法来实现该方法,以及为什么没有方法“直接”生成所需范围内的值。

Hoopje在他的回答中已经指出了一个重要的问题:原因可能是0.0到1.0之间的范围更适合于表示均匀分布的值。

当查看(或者更确切地说是:仔细阅读)有关IEEE 754浮点数格式的详细信息时,您将看到值的密度随着值的增大而减小。

当您启动一个IEEE计算器并输入0.0、1.0和1.70141*10^38的值时,您将看到它们的表示(这里是float -类似于适用于double的语句):

代码语言:javascript
复制
0.0          =  0x00000000 = 0
1.0          =  0x3F800000 = 1065353216
1.7...*10^38 =  0x7EFFFFFE = 2130706430

实际上,0.0到1.0之间的浮点数与1.0到17014116317805962800168797686300000.0之间的数字基本相同。实现一个好的、一致的随机数生成器并不容易,考虑到可表示值本身并不是均匀分布的问题,为任意范围创建专用实现是不可能的。

因此,对于0.0到1.0的范围,可以用实心声明值是均匀分布的。对于其他范围,人们将不得不争论什么“统一性”应该实际意味着一个特定的范围.

票数 2
EN

Stack Overflow用户

发布于 2016-12-21 18:40:10

我想让您了解一下API设计的动机。这有点推测,但选择的设计至少有一个很好的理由,即它很容易正确实现,同时仍然可以提供任意大小的随机数(因为您可以缩放结果)。

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41269163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档