【问题标题】:Generating a random double number of a certain range in Java在Java中生成一定范围的随机双数
【发布时间】:2012-03-15 16:16:46
【问题描述】:

我看过几乎解释了这个问题的帖子,但它们都使用整数值,老实说我并不完全理解它,因此这个问题:

我正在尝试在 java 中生成从 (-1554900.101) 到 (52952058699.3098) 范围内的随机数,我想知道是否有人可以向我解释这一点,因为我真的很想理解它。

我的想法: 这将是一个正确的方法吗? 1)在我指定的范围内生成一个随机整数 2) 生成的数字除以 pi 得到 float/double 随机结果

提前致谢。

【问题讨论】:

标签: java random


【解决方案1】:

这就是想法。你想要一个范围中的随机数,比如说[-1.1,2.2],从一个简单的例子开始。自 2.2 - (-1.1) = 3.3 以来,该范围的长度为 3.3。现在大多数“随机”函数返回一个范围为 [0,1) 的数字,其长度为 1,因此我们必须将随机数缩放到我们想要的范围内。

Random random = new Random();
double rand = random.nextDouble();
double scaled = rand * 3.3;

现在我们的随机数具有我们想要的大小,但我们必须将它在数轴上移动到我们想要的确切值之间。对于这一步,我们只需要将整个范围的下限添加到缩放后的随机数中,我们就完成了!

double shifted = scaled + (-1.1);

所以现在我们可以将这些部分放在一个函数中:

protected static Random random = new Random();
public static double randomInRange(double min, double max) {
  double range = max - min;
  double scaled = random.nextDouble() * range;
  double shifted = scaled + min;
  return shifted; // == (rand.nextDouble() * (max-min)) + min;
}

当然,这个函数需要对像NaN这样的意外值进行一些错误检查,但是这个答案应该能说明一般的想法。

【讨论】:

  • 如果我使用Double.MAX_VALUEDouble.MIN_VALUE,你最后一个sn-p 中的第3 行不会超出范围吗?
【解决方案2】:
double lower = -1554900.101;
double upper = 52952058699.3098;
double result = Math.random() * (upper - lower) + lower;

【讨论】:

  • 但是 OP 正在寻找一个解释,而不是从intdouble 类型的翻译...
【解决方案3】:

我不会这样做。

  • 生成随机双精度。结果介于 0 和 1 之间。
  • 将此数字乘以 (highLimit - lowLimit) (52952058699.3098 - -1554900.101)
  • 添加下限(随机 + -1554900.101)

给你。你有一个介于上下限之间的随机数。

【讨论】:

    【解决方案4】:

    应该是这样的:

    double rnd = Math.random();
    
    double result = ((long)(rnd * (529520586993098L - (-15549001010L) + 1)) -15549001010L) / 10000.0;
    

    + 1 将平衡范围为 [0;1[ 的事实,因此排除了上限。

    我们首先尝试找到一个“整数”(真的很长)范围,我们加 1 以平衡排除最后一个数字的事实,所以 529520586993098L + 15549001010L + 1,然后我们将它乘以 rnd,将其转换为 @ 987654326@ 并减去 15549001010L 以将其移回,最后将其除以 10000.0 以使其在正确的“范围”内。

    这可能更清楚:

    long range = 529520586993098L + 15549001010L + 1;
    
    double temp = rnd * range;
    long temp2 = (long)temp;
    temp2 -= 15549001010L;
    
    double result = temp2 / 10000.0;
    

    【讨论】:

      【解决方案5】:

      Random.nextDouble 在 [0, 1[ 范围内返回一个双精度值,因此使用它,乘以您的范围大小 (52952058699.3098 + 1554900.101),然后偏移结果(减去 1554900.101)以获得您的号码。

      虽然不确定您需要多少精确,但如果不做进一步分析,由于双打的处理方式,您可能会得到超出范围的数字。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-08
        • 1970-01-01
        • 2011-07-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-06
        • 1970-01-01
        • 2014-01-29
        相关资源
        最近更新 更多