Javascript 在指定范围内生成随机数-各种情况(int、float、inclusive、exclusive)
给定一个Javascript 在指定范围内生成随机数-各种情况(int、float、inclusive、exclusive),javascript,random,floating-point,integer,range,Javascript,Random,Floating Point,Integer,Range,给定一个Math.random()函数,该函数返回一个介于[0,1)和minmax值之间的数字来指定范围,我们如何为以下情况生成数字: 需要整数的情况下: A:(最小值,最大值)? B:[min,max]返回Math.floor(Math.random()*(max-min))+min; C:(最小值,最大值)? D:[min,max]返回Math.floor(Math.random()*(max-min+1))+min; 我们想要浮动的情况下: A:(最小值,最大值)? B:[min,m
Math.random()
函数,该函数返回一个介于[0,1)和min
max
值之间的数字来指定范围,我们如何为以下情况生成数字:
需要整数的情况下:
A:(最小值,最大值)?
B:[min,max]返回Math.floor(Math.random()*(max-min))+min;
C:(最小值,最大值)?
D:[min,max]返回Math.floor(Math.random()*(max-min+1))+min;
A:(最小值,最大值)?
B:[min,max)返回Math.random()*(max-min)+min;
C:(最小值,最大值)?
D:[最小值,最大值]?
- 答:
返回Math.floor(Math.random()*(max-min-1))+min+1;
- B:对
- C:这与[min+1,max+1]相同,因此:
返回Math.floor(Math.random()*(max-min))+min+1;
- D:对
返回Math.random()*(max-min)+min;
为了使问题有意义,您需要定义一个最小可接受的相等范围(例如r=0.0000000000000000 1
)。然后您可以将开放范围方程(即(min,max)
)转换为[min+r,max-r]
整数
你的B.公式是正确的,其他的都是通过简单的+1
-1
修正得到的:
- A.
,因此从B.我们获得(最小,最大)=[min+1,最大)
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))
- 因此:
min+Math.floor(Math.random()*(max+1-min))
<强>浮点.V13已经指出,这个问题有点不适定:如果我们把单点当作度量零点集,则几乎(在理论上意义上)这四个集合之间没有差别……但是,如果你想保证排除的间隔边界永远不会(不只是“几乎从不”)采样后,如果假设没有舍入错误,可以执行以下操作:
- 答:
此解决方案在var middle=(min+max)/2;var sign=Math.random()>0.5?1:-1;返回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之间的区别如下:如果我们尝试在A中使用公式
min+Math.random()*(max-min)
,我们偶尔会得到0
(因为可能的数字范围实际上是有限的)但是,没有任何合理的统计数据可以抱怨D中没有达到上限。我将首先定义接下来的两个帮助函数,然后使用它们来获取值。这些方法是您对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;
}
然后对于整数
- A:返回下一个(最小值+1,最大值)
- B:返回下一个(最小值、最大值)
- C:返回nextInt(最小值+1,最大值+1)
- D:返回下一个(最小值,最大值+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中max的可能性-如果参考函数完全一致(通常不一致),则该值的概率比任何其他值都稍高,但通常这只是一个理论问题。(准确地说,如果该范围内有n个可能值,则最大值pmax=1/(n-1)的概率和任何其他值的概率为(1-pmax)/(n-1))
应该注意在精确实现浮点情况A时应注意的一个小问题。函数的调用方可能会使用相邻的浮点调用它。通过对参数的任何伪检查都不容易看出这一点,因此为了安全起见,应该对循环ma的次数进行限制y将被执行。我的参考来自您的float B