2015-10-16 56 views
11

给定一个Math.random()函数返回一个介于[0,1)和min之间的数字max值来指定范围,我们如何生成数字如下例:生成指定范围内的随机数 - 各种情况(int,float,inclusive,exclusive)

情况下,我们希望整数

  • A: (min,max) ?
  • B: [min,max) return Math.floor(Math.random() * (max - min)) + min;
  • C: (min,max] ?
  • D: [min,max] return Math.floor(Math.random() * (max - min + 1)) + min;

情况下,我们希望浮动

  • A: (min,max) ?
  • B: [min,max) return Math.random() * (max - min) + min;
  • C: (min,max] ?
  • D: [min,max] ?
+0

我的引用来自[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) – tgogos

+0

我正在纠正 –

+0

您的'float B'情况不起作用:在许多情况下,该公式将能够产生上限和下限。 –

回答

0

整数:

  • 答:return Math.floor(Math.random() * (max - min - 1)) + min + 1;
  • B:正确
  • C:这是相同的[分钟+ 1,最多+ 1),所以:return Math.floor(Math.random() * (max - min)) + min + 1;
  • d:正确

对于浮点数,你需要知道你有什么样的浮点算法。除非你使用一个特殊的库,否则浮点数的平等通常是不会发生的,所以关闭范围是没有意义的。因此应该有四个没有区别,你可以只是去:

return Math.random() * (max-min) + min;

对于这个问题是有道理的,你需要定义为平等的最低可接受的范围(如r=0.00000000000000001)。之后,您可以将开放式范围方程式(即(min, max))转换为[min+r, max-r]

2

整数 您的B.公式是正确的,其他一切都是由琐碎+1-1更正获得:

  • A. (min, max) = [min + 1, max),因此从B.我们得到 min + 1 + Math.floor(Math.random() * (max - min - 1))
  • B. min + Math.floor(Math.random() * (max - min))
  • C.由于区间算术(min, max] = max - [0, max - min),人们也可以写max - Math.floor(Math.random() * (max - min))
  • D.[min, max] = [min, max + 1),因此:min + Math.floor(Math.random() * (max + 1 - min))

浮子。由于V13已经指出,这个问题有些不适当:如果我们考虑单点作为度量零集,几乎(在测量理论上)四个集之间没有区别...但是,如果你想以保证排除间隔边界从来不(不只是“几乎没有”)采样,如果你认为没有舍入误差,你可以做这样的事情:

  • 答:var middle = (min + max)/2; var sign = Math.random() > 0.5 ? 1 : -1; return middle + sign * (max - min)/2 * Math.random();该解决方案将在0上的质量稍微有点多,但对于所有实际目的而言,这应该可以忽略不计。

  • B:min + Math.random() * (max - min),是的。

  • C:max - Math.random() * (max - min),与上述对称。
  • D:我们不能保证我们碰到了上部区间边界,所以我们可以使用min + Math.random() * (max - min)

A和d之间的区别是:如果我们试图用公式min + Math.random() * (max - min)在A,我们有时可能会得到一个0(因为可以数的范围实际上是有限的)。然而,没有合理的统计数据可以抱怨上限不在D中。

0

我将从定义接下来的两个辅助函数开始,然后使用它们来获取值。这些方法是您对B案例的定义。

int nextInt(int min, int max) { 
    return Math.floor(Math.random() * (max - min)) + min; 
} 

float nextFloat(float min, float max) { 
    return Math.random() * (max - min) + min; 
} 

然后为整数

  • 答:返回nextInt(分钟+ 1,最多);
  • B:return nextInt(min,max);
  • C:return nextInt(min + 1,max + 1);
  • D:return nextInt(min,max + 1);

浮动是一个更复杂的情况。有些人可能会争辩说,终点是否包含在内没有太大的区别 - 尤其是可以使用开放式解决方案而不是关闭 - 因为终点很少被选中。但是由于完全可能实现所有场景,我认为数据如何可以完成。

答:在这种情况下,我们可以简单的确保非法值再次卷起:

float f; 
do { 
    f = nextFloat(min, max); 
} while (f == min); 
return f; 

B:

return nextFloat(min, max); 

C:在这里,我们只需切换端点

float f = nextFloat(min, max); 
if (f == min) { 
    return max; 
} 
return f; 

d:这是所有的最复杂的情​​况,但可以如下实现:

float f = nextFloat(min, max); 
if (f == min) { 
    return max; 
} 
return nextFloat(min, max); 

的情况下,A和d是在这个意义上有点脏,他们可能需要产生一个以上随机数,这可能是一些特定情况下的问题。解决这个问题需要深入研究浮点的规范以寻找替代实现。此外,应该注意的是,在情况D中,最大值的可行性比任何其他数字具有稍高的可行性,如果所引用的函数是完全一致的(通常不是),但通常这仅仅是理论问题。 (具体而言,如果在该范围内有n个可能值,则最大值pmax = 1 /(n-1)的可行性和任何其他值的可行性是(1-pmax)/(n-1))。

应该注意到浮点事例A的精确实现中应该注意的一个小问题。函数的调用者有可能会用相邻的浮点调用它。通过对参数进行虚拟检查并不容易,所以为了安全起见,应该限制循环执行的次数。

相关问题