如何在JavaScript中的两个指定变量之间生成随机整数,例如x=4和y=8将输出4、5、6、7、8中的任意一个?
当前回答
Use:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
/*
Assuming that window.crypto.getRandomValues
is available, the real range would be from
0 to 1,998 instead of 0 to 2,000.
See the JavaScript documentation
for an explanation:
https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues
*/
var array = new Uint8Array(2);
window.crypto.getRandomValues(array);
console.log(array[0] + array[1]);
</script>
</body>
</html>
Uint8Array创建一个最多三位数的数组,最大值为999。这段代码很短。
其他回答
其他答案没有考虑到0和1这两个完全合理的参数。相反,您应该使用圆形而不是天花板或地板:
function randomNumber(minimum, maximum){
return Math.round( Math.random() * (maximum - minimum) + minimum);
}
console.log(randomNumber(0,1)); # 0 1 1 0 1 0
console.log(randomNumber(5,6)); # 5 6 6 5 5 6
console.log(randomNumber(3,-1)); # 1 3 1 -1 -1 -1
Mozilla开发者网络页面上有一些示例:
/**
* Returns a random number between min (inclusive) and max (exclusive)
*/
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
/**
* Returns a random integer between min (inclusive) and max (inclusive).
* The value is no lower than min (or the next integer greater than min
* if min isn't an integer) and no greater than max (or the next integer
* lower than max if max isn't an integer).
* Using Math.round() will give you a non-uniform distribution!
*/
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
这是背后的逻辑。这是一个简单的三条规则:
Math.random()返回一个介于0(含)和1(不含)之间的数字。所以我们有一个这样的间隔:
[0 .................................... 1)
现在,我们需要一个介于min(含)和max(不含)之间的数字:
[0 .................................... 1)
[min .................................. max)
我们可以使用Math.random获取[min,max)区间的对应值。但是,首先我们应该通过从第二个区间减去min来稍微考虑一下问题:
[0 .................................... 1)
[min - min ............................ max - min)
这给出了:
[0 .................................... 1)
[0 .................................... max - min)
我们现在可以应用Math.random,然后计算对应的。让我们选择一个随机数:
Math.random()
|
[0 .................................... 1)
[0 .................................... max - min)
|
x (what we need)
因此,为了找到x,我们需要:
x = Math.random() * (max - min);
别忘了把min加回来,这样我们就可以得到[分钟,最大值]间隔内的数字:
x = Math.random() * (max - min) + min;
这是MDN的第一个函数。第二个,返回一个介于min和max之间的整数,两者都包含在内。
现在,对于整数,可以使用round、ceil或floor。
您可以使用Math.round(Math.random()*(max-min))+min,但这给出了一个非偶数分布。最小值和最大值都只有大约一半的掷骰机会:
min...min+0.5...min+1...min+1.5 ... max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max
如果将最大值排除在区间之外,那么它比最小值滚动的机会更小。
使用Math.floor(Math.random()*(max-min+1))+min,您可以获得完全均匀的分布。
min... min+1... ... max-1... max.... (max+1 is excluded from interval)
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘ ← Math.floor()
min min+1 max-1 max
你不能在这个等式中使用ceil()和-1,因为max现在的掷骰机会稍微少了一些,但你也可以掷(不需要的)min-1的结果。
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
// Example
function ourRandomRange(ourMin, ourMax) {
return Math.floor(Math.random() * (ourMax - ourMin + 1)) + ourMin;
}
ourRandomRange(1, 9);
// Only change code below this line.
function randomRange(myMin, myMax) {
var a = Math.floor(Math.random() * (myMax - myMin + 1)) + myMin;
return a; // Change this line
}
// Change these values to test your function
var myRandom = randomRange(5, 15);
Math.random()快速且适用于许多目的,但如果您需要密码安全的值(它不安全),或者如果您需要来自完全一致的无偏分布的整数(其他答案中使用的乘法方法产生某些值的频率略高于其他答案),则不适用。
在这种情况下,我们可以使用crypto.getRandomValues()生成安全整数,并拒绝任何无法统一映射到目标范围的生成值。这会比较慢,但除非您正在生成大量的值,否则这不会有意义。
为了澄清偏差分布问题,请考虑这样一种情况:我们希望生成1到5之间的值,但我们有一个随机数生成器,它生成1到16之间的值(4位值)。我们希望将相同数量的生成值映射到每个输出值,但16不能被5整除:它留下1的余数。因此,我们需要拒绝1个可能生成的值,只有当我们得到15个较小的值中的一个值时才能继续,这些值可以统一映射到我们的目标范围中。我们的行为可能类似于以下伪代码:
Generate a 4-bit integer in the range 1-16.
If we generated 1, 6, or 11 then output 1.
If we generated 2, 7, or 12 then output 2.
If we generated 3, 8, or 13 then output 3.
If we generated 4, 9, or 14 then output 4.
If we generated 5, 10, or 15 then output 5.
If we generated 16 then reject it and try again.
下面的代码使用了类似的逻辑,但生成了一个32位整数,因为这是JavaScript的标准数字类型可以表示的最大公共整数大小。(如果需要更大的范围,可以将其修改为使用BigInts。)无论选择的范围如何,生成的被拒绝值的比例始终小于0.5,因此预期的拒绝数始终小于1.0,通常接近0.0;你不必担心它会永远循环。
常量随机整数=(最小值,最大值)=>{常量范围=最大值-最小值;常量maxGeneratedValue=0xFFFFFFFF;const possibleResultValues=范围+1;const possibleGeneratedValues=最大生成值+1;常量余数=possibleGeneratedValues%possibleResultValues;const maxUnbiased=maxGeneratedValue-余数;if(!Number.isInteger(min)||!Number.isInteger(最大值)||max>Number.max_SAFE_INTEGER||min<Number.min_SAFE_INDEGER){抛出新错误(“参数必须是安全整数。”);}否则如果(范围>maxGeneratedValue){抛出新错误(`范围为${Range}(从${min}到${max})>${maxGeneratedValue}。`);}否则,如果(最大值<最小值){抛出新错误(`max(${max})必须>=min(${min})。`);}否则如果(min==max){返回最小值;} let生成;做{generated=crypto.getRandomValues(新Uint32Array(1))[0];}而(生成>maxUnbiased);return min+(生成的%possibleResultValues);};console.log(randomInteger(-8,8));//-2.console.log(randomInteger(0,0));//0console.log(随机整数(0,0xFFFFFFFF));//944450079console.log(随机整数(-1,0xFFFFFFFF));//错误:4294967296覆盖-1到4294967295的范围>4294967295。console.log(new Array(12).fill().map(n=>randomInteger(8,12)));// [11, 8, 8, 11, 10, 8, 8, 12, 12, 12, 9, 9]
推荐文章
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 将整数转换为字符串,以逗号表示千
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格
- JavaScript: override alert()
- 重置setTimeout
- 如何确保<select>表单字段被禁用时提交?
- jQuery有不聚焦的方法吗?
- 反应钩子-正确的方式清除超时和间隔
- TypeScript枚举对象数组
- 在React.js中正确的img路径
- 在React.js中更新组件onScroll的样式
- onClick ReactJS调用多个函数
- 如何在JavaScript中转义单引号(')?