Java中math.random的分布是怎样的?

Bam*_*omy -3 java random

我想在 Java 程序中使用 math.random() 。

这种获得双打的方式的分布是怎样的?

ζ--*_*ζ-- 8

Java SE API 文档中记录了这一点:

public static double random()

返回带正号的双精度值,大于或等于 0.0 且小于 1.0。返回值是伪随机选择的,在该范围内(近似)均匀分布。

该文档继续提到它java.util.Random在幕后使用,大概是 nextDouble() (尽管没有明确说明)。

nextDouble中关于不均匀性的注释如下:

nextDouble 方法由 Random 类实现,如下所示:

 public double nextDouble() {
   return (((long)next(26) << 27) + next(27))
     / (double)(1L << 53);
 }
Run Code Online (Sandbox Code Playgroud)

在前面的描述中使用对冲“大约”只是因为下一个方法只是大约独立选择的位的无偏源。如果它是随机选择位的完美来源,则所示算法将从指定范围中以完美的均匀性选择双精度值。

看起来不均匀性只是由于潜在的不均匀性next而不是 nextDouble 算法本身的显着偏差造成的:

[在Java的早期版本中,结果被错误地计算为:

  return (((long)next(27) << 27) + next(27))
     / (double)(1L << 54);
Run Code Online (Sandbox Code Playgroud)

这看起来似乎是等价的,甚至更好,但事实上,由于浮点数舍入的偏差,它引入了很大的不均匀性:有效数的低位为 0 的可能性是其三倍比那将是1!这种不均匀性在实践中可能并不重要,但我们力求完美。]

请注意,这从间隔 [0,1] 均匀绘制,分为 2 -53的相等步长,这与从值在 0 到 1 之间的所有值的集合均匀绘制不同。double是一个微妙的区别: 0 到 1 之间的所有值的集合double本身在数轴上的间隔并不均匀,如下图所示:

在此输入图像描述

图片转载自docs.oracle.com