模拟Math.random()的最大值

时间:2015-01-15 06:58:11

标签: java random

我正在嘲笑Java中random()类的静态Math方法,以更好地测试依赖于生成随机数的方法。我使用的代码如下:

@Mock
public double random() {
    return 1.0 - Double.MIN_VALUE;
}

这是我尝试在不相等的情况下尽可能接近1.0的值。 (例如0.999999999999 ......)

但是,当我调用模拟的Math.random()方法时,我总是得到1.0作为值。它几乎就像减去Double.MIN_VALUE一样,根本不会影响1.0。

为什么1.0 - Double.MIN_VALUE会产生1.0,我如何模拟Math.random()的最大可能值?

3 个答案:

答案 0 :(得分:2)

double具有限制精度。可以表示为double的最接近1.0 - Double.MIN_VALUE的数字是1.0。这就是你得到1.0的原因。

双精度符号为1位,指数为11位,分数为52位。 (Source

由64位表示的double值为(-1)^sign+1.b51b50...b0 x 2^(e-1023)

最接近1.0的是当所有分数位为1且指数为e-1023==-1时。 该值为二进制0.1111..111(53个)。

以小数形式获取该值:

double d = 0.0;
double exp =1.0;
for (int i=1;i<=53;i++) {
  exp=exp*2.0;
  d+=1.0/exp;
}
System.out.println (d);
System.out.println ("d==1.0? " + (d==1.0));

打印

0.9999999999999999
d==1.0? false

如果你在循环中添加另一个迭代(即i<=54),你得到:

1.0
d==1.0? true

答案 1 :(得分:1)

根据IEEE 754 double有15.95个十进制数字

http://en.wikipedia.org/wiki/IEEE_floating_point

因此,如果您尝试double a = 1e0 - 1e-16 //or less,您将获得== 1e0

答案 2 :(得分:1)

double不够精确,无法显示执行1.0 - Double.MIN_VALUE时生成的数字。在讨论Java原始类型时,指出了here。您可能会发现此答案也很有趣:https://stackoverflow.com/a/15736977/4381697