我该如何在 JavaScript 中生成在两个指定变量之间的随机整数,例如 x = 4
和 y = 8
会输出 4, 5, 6, 7, 8
中的任意一个?
我该如何在 JavaScript 中生成在两个指定变量之间的随机整数,例如 x = 4
和 y = 8
会输出 4, 5, 6, 7, 8
中的任意一个?
在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(不包括)之间的Number
。因此,我们有了这样一个区间:
[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
,这样我们就可以获得在 [min, max) 区间内的数字。x = Math.random() * (max - min) + min;
这是来自MDN的第一个函数。第二个函数会返回介于min
和 max
之间(包含两端)的整数。
现在要获取整数,你可以使用round
、ceil
或floor
。
你可以使用Math.round(Math.random() * (max - min)) + min
,但这将导致非均匀分布。因为min
和max
只有约一半的机会被选中:
min...min+0.5...min+1...min+1.5 ... max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max
在排除 max
的情况下,它滚动的机会比 min
还要少。
使用 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
的结果。
min
和max
仅有其他数字一半的机会来投掷。您也可以减去1并使用“ ceil”函数。但这会使得max
数字由于在[0,1)区间内而变得更难被投掷到。 - Christophvar randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
(Math.random() * (maximum - minimum + 1) ) << 0
更快。 - Ismael Miguelx << 0
, x | 0
, ~~x
) 替代 Math.floor()
将会将 x
转换成一个范围比 Number.MAX_SAFE_INTEGER
(2⁵³) 小得多的二补数形式(2³²⁻¹),因此使用时必须小心谨慎! - le_m657348096152|0
,则会得到218099864(二进制中的1100111111111111000010011000)。 - Ismael Miguelfunction randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randomNumber(min, max) {
return Math.random() * (max - min) + min;
}
有用的例子(整数):
// 0 -> 10
Math.floor(Math.random() * 11);
// 1 -> 10
Math.floor(Math.random() * 10) + 1;
// 5 -> 20
Math.floor(Math.random() * 16) + 5;
// -10 -> (-2)
Math.floor(Math.random() * 9) - 10;
** 始终不要忘记(Mozilla):
Math.random()不能提供加密安全的随机数。不要在与安全相关的任何事情上使用它们。请改用Web Crypto API,并更精确地使用window.crypto.getRandomValues()方法。
+1
。 - Alexander Farber使用:
function getRandomizer(bottom, top) {
return function() {
return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
}
}
使用方法:
var rollDie = getRandomizer( 1, 6 );
var results = ""
for ( var i = 0; i<1000; i++ ) {
results += rollDie() + " "; // Make a string filled with 1000 random numbers in the range 1-6.
}
简述:
我们正在返回一个函数(借鉴于函数式编程),当调用该函数时,它将返回介于bottom
和top
值之间的随机整数, 包括bottom
和top
。 我们说“包含”,因为我们想在可返回的数字范围内包括底部和顶部。这样,getRandomizer( 1, 6 )
将返回1、2、3、4、5或6中的任意一个。
('bottom'是较小的数字,'top'是较大的数字)
Math.random() * ( 1 + top - bottom )
Math.random()
返回一个介于0和1之间的随机双精度浮点数,如果我们将其乘以top
和bottom
之差加1,我们将得到一个介于0
和1+b-a
之间的双精度浮点数。
Math.floor( Math.random() * ( 1 + top - bottom ) )
Math.floor
函数向下取整到最近的整数。因此,我们现在拥有0
和top-bottom
之间的所有整数。1看起来很困惑,但它必须存在,因为我们总是向下取整,所以实际上永远不会达到最大值,除非加上它。我们生成的随机小数需要在 0
到 (1+top-bottom)
范围内,这样我们才能向下取整并得到 0
到 top-bottom
范围内的整数:
Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom
在前面的示例代码中,我们得到了一个介于0
和top-bottom
之间的整数,现在我们只需要将bottom
加到该结果中,以获得一个范围在bottom
和top
(包括两端)之间的整数。 :D
注意:如果您传入非整数值或者先传入较大的数字,则会出现不良行为,但除非有人要求,否则我不会深入探讨参数检查代码,因为这与原始问题的意图相去甚远。
Math.random() * 10 | 5
只会输出 5 | 7 | 13
。 - avalanche1|
位或运算符是什么意思。按照现有的陈述,此解决方案适用于下限为 0
,上限为非包含性的最大值之间的数字。 - aefxx返回1到10之间的随机数:
Math.floor((Math.random()*10) + 1);
返回1到100之间的随机数:
Math.floor((Math.random()*100) + 1)
function randomRange(min, max) {
return ~~(Math.random() * (max - min + 1)) + min
}
如果你正在使用Underscore.js,那么可以使用以下替代方案:
_.random(min, max)
_.uniqueId()
函数,您可以为客户端模型调用该函数。 - originalhatx << 0
,x | 0
,~~x
)而不是 Math.floor()
将 x
转换为一个二补数,其范围比 Number.MAX_SAFE_INTEGER
(2³²⁻¹ vs. 2⁵³)小得多,因此必须谨慎使用! - le_m如果您需要一个介于0和最大值之间的变量,可以使用:
Math.floor(Math.random() * max);
max
包含在内,请使用 (max + 1)
。不要使用 Math.round()
,因为这会破坏范围两端的 _随机分布_。 - Dem Pilafian其他答案没有考虑到 0
和 1
这些完全合理的参数。相反,您应该使用 round
而不是 ceil
或 floor
:
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
console.log(randomNumber(5,6)); # 9 6 6 5 7 7
9和7是否在5和6之间?......你应该纠正它或解释一下。 - Sachin要在区间[x,y]内获取一个密码学强度的随机整数,请尝试:
let cs = (x,y) => x + (y - x + 1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32 | 0
console.log(cs(4, 8))
(x, y) => x + crypto.getRandomValues(new Uint32Array(1))[0] % (y - x + 1)
(整数取模而非浮点除法)。 - user2297550Math.random()
不同? - Bryan K