Java SE API 文档中记录了这一点:
public static double random()返回带正号的双精度值,大于或等于 0.0 且小于 1.0。返回值是伪随机选择的,在该范围内(近似)均匀分布。
该文档继续提到它java.util.Random在幕后使用,大概是 nextDouble() (尽管没有明确说明)。
nextDouble中关于不均匀性的注释如下:
nextDouble 方法由 Random 类实现,如下所示:
Run Code Online (Sandbox Code Playgroud)public double nextDouble() { return (((long)next(26) << 27) + next(27)) / (double)(1L << 53); }在前面的描述中使用对冲“大约”只是因为下一个方法只是大约独立选择的位的无偏源。如果它是随机选择位的完美来源,则所示算法将从指定范围中以完美的均匀性选择双精度值。
看起来不均匀性只是由于潜在的不均匀性next而不是 nextDouble 算法本身的显着偏差造成的:
[在Java的早期版本中,结果被错误地计算为:
Run Code Online (Sandbox Code Playgroud)return (((long)next(27) << 27) + next(27)) / (double)(1L << 54);这看起来似乎是等价的,甚至更好,但事实上,由于浮点数舍入的偏差,它引入了很大的不均匀性:有效数的低位为 0 的可能性是其三倍比那将是1!这种不均匀性在实践中可能并不重要,但我们力求完美。]
请注意,这从间隔 [0,1] 均匀绘制,分为 2 -53的相等步长,这与从值在 0 到 1 之间的所有值的集合均匀绘制不同。这double是一个微妙的区别: 0 到 1 之间的所有值的集合double本身在数轴上的间隔并不均匀,如下图所示:
图片转载自docs.oracle.com