在Double域中生成Double

时间:2014-06-16 21:41:04

标签: java random

根据this question,要在给定范围内创建双号,您可以使用:

Random r = new Random();
double randomValue = rangeMin + (rangeMax - rangeMin) * r.nextDouble();

我正在尝试使用上面提到的相同代码在双域[Double.MIN_VALUE, Double.MAX_VALUE]中生成一个双号:

package test;

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        double lower = Double.MIN_VALUE;
        double upper = Double.MAX_VALUE;
        Random   rand = new Random();

        for (int i = 0; i < 200; i++) {
            double a = lower + (upper - lower) * rand.nextDouble();
            System.out.println(a);
        }
    }
}

然而,即使经过多次迭代,我也只得到正数:

1.436326007111308E308
2.7068601271148073E307
1.266896721067985E308
8.273233207049513E306
1.3338832492644417E308
8.584898485464862E307
1.260909190772451E308
1.5511066198317899E307
1.2083062753983258E308
2.449979496663398E307
7.333729592027637E307
7.832069948910962E307
8.493365260900201E307
5.158907971928131E307
3.126231202546818E307
1.3576316635349233E308
1.0991793636673692E308
6.991662398870649E307

我的问题是:如何在双倍范围内生成双数?

3 个答案:

答案 0 :(得分:1)

结果与预期不符,因为MIN_VALUE是最小的 double值。可能的最小double值为-Double.MAX_VALUE(请注意减号)。

您不能简单地使用lower = -Double.MAX_VALUE,因为这样,差异将无法表示为double,并且会溢出。

第一个想法就像是

double d = random.nextDouble() * Double.MAX_VALUE;
if (random.nextBoolean()) d = -d;

覆盖整个可能的范围。


编辑:A(可能是次要的):建议的方法也应该涵盖负double值,并且应该是正确的,因为每个可能的值都以正数或负数形式显示概率相等。但是,它将无法返回值Double.MAX_VALUE(因为Random#nextDouble()返回的值严格小于1.0)。但基于nextDouble的实现,无论如何可能会double值永远不会出现在输出中。

答案 1 :(得分:0)

Double.MIN_VALUE是您可以表示为double的最小值。

这不是最大的负数。这将是-Double.MAX_VALUE

答案 2 :(得分:0)

正如我在评论中所说,其他人也说,MIN_VALUE是积极的。但即使您使用-Double.MAX_VALUE,计算upper - lower时计算也会溢出双精度,因为结果将是最大双倍的两倍!解决这个问题的一种方法是:

val = Random.nextDouble();
return (val < 0.5) ? (-2 * val) * Double.MAX_VALUE : (2 * (val - 0.5)) * Double.MAX_VALUE;