在JavaScript中生成两个数字之间的随机数


1795

有没有办法在JavaScript中生成指定范围(例如1到6:1、2、3、4、5或6)内的随机数?


12
Math.floor(Math.random()* 7)
Amjad Masad 2011年

65
当然。Math.floor(Math.random()* 6 + 1)
Amjad Masad 2011年

3
Nabil Kadimi也写了一篇关于如何生成负随机数的文章。
madc 2012年

这是一个有用的要点:gist.github.com/kerimdzhanov/7529623
Dan KK

为什么这样的解决方案Math.floor((Math.random()*10)+1);无法按照w3schools.com/jsref/jsref_random.asp ..中的指定为您工作?
shashwat 2014年

Answers:


2115

重要

以下代码仅在最小值为时才有效1。不适用于除以外的最小值1

如果您想获得介于1(只有1)和6 之间的随机整数,则可以计算:

Math.floor(Math.random() * 6) + 1  

哪里:

  • 1是起始号码
  • 6是可能的结果数(1 +开始(6) -结束(1)

45
@Mike可以正常工作,但最好指出更通用的版本,因为Francisc在下面有它:-)。
雷蒙德·麦基拉

58
-1。在谷歌搜索之后,我发现了这个问题,标题是“在JavaScript中生成两个数字之间的随机值”。如果最小值为0,则无法使用
Ydhem 2013年

18
如果您想要一个介于两个较大数字之间的数字,则无效。Math.floor(Math.random()* 900)+ 700
Rob

14
仅在最小值为1的情况下有效。如果最小值为2,并且我们仍然使用Math.floor(Math.random() * 6) + 2意味着如果Math.random()结果为0.99 ,则我们的随机值为7
抗毒

27
此代码不好,因为它不适用于任何数字。@Francisc代码是正确的。
狮子王

2283
function randomIntFromInterval(min, max) { // min and max included 
  return Math.floor(Math.random() * (max - min + 1) + min);
}

它“额外”的作用是允许以1开头的随机间隔。因此,例如,您可以获得10到15之间的随机数。灵活性。


5
这也很棒,因为如果有人不包含toarg,则fromarg会以最大的两倍加倍
Jason

12
你好。这来自MDN:Returns a floating-point, pseudo-random number in the range [0, 1) that is, from 0 (inclusive) up to but not including 1 (exclusive), which you can then scale to your desired range.developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Francisc

5
阅读以上评论。随机数位于[0,1)内部,而不位于[0,1]内部。
Francisc

3
伟大的作品,如果较低的数字为0
罗宾齐默尔曼

2
请注意,仅当min和max为整数时,此解决方案才是正确的,否则您可以在[min,ceil(max)]区间获得结果。也就是说,您得到的结果超出范围,因为高于最大值。
collimarco 2014年

326

Math.random()

返回介于min(包括)和max(包括)之间的整数随机数

function randomInteger(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

或介于min(包括)和max(不包括)之间的任何随机数

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()方法。


令我感到困惑的是……Math.floor(..)确保该数字是整数,其中Math.round(..)会给出不均匀的分布。参考:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…–
alikuli

1
我相信这个答案。任何人都可以给出链接或清楚说明其工作原理吗?也许是Math.round如何产生偏差的一个例子,为什么这意味着我们必须使用这个看起来很复杂的公式?
罗宾·安德鲁斯

6
@alikuli对于范围的[1,2],有25%的机会Math.random()将使你从这些一个一个数[0,0.49][0.5,0.99][1,1.49][1.5,1.99]。四舍五入这些间隔将导致0、1、1、2,这不是均匀分布。地板它们导致0,0,1,1
monkapish

1
@shuji这除其他外的正确答案。我只是想说明为什么使用Math.roundover Math.floor会产生不同的结果。
monkapish

我找到的最准确的解决方案: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }
Sadik

91

其他解决方案:

  • (Math.random() * 6 | 0) + 1
  • ~~(Math.random() * 6) + 1

在线尝试


6
您介意解释〜或sintaxis吗?我没看过!优雅的解决方案,但很难理解。
DiegoDD

27
Double Tilde ~~a按位或(a | 0)是编写Math.floor(a)的更快方法
edi9999 2013年

7
a | 0也是将字符串转换为整数的最快,最优化的方法。它仅适用于包含整数("444""-444")的字符串,即没有浮点数/分数。0失败的一切都会产生一个。它是asm.js背后的主要优化之一。
pilau 2014年

3
注意:如果使用的是非常大的数字,则双波浪号将不起作用。尝试~~(Math.random() * (50000000000000 - 0 + 1)) + 0Math.floor(Math.random() * (50000000000000 - 0 + 1)) + 0
BrunoLM

3
“双波浪号和按位OR /是编写Math dot floor的更快方法”是一首美丽的押韵对联,使我的早晨更加光彩。感谢@ edi9999!
teedyay '18

60

TL; DR

function generateRandomInteger(min, max) {
  return Math.floor(min + Math.random()*(max + 1 - min))
}

获取随机数 generateRandomInteger(-20, 20);

解释如下

我们需要获得一个随机整数,例如介于最小值和最大值之间的X。

对?

min <= X <= max

如果我们从方程式中减去最小值,则等于

0 <=(X-最小)<=(最大-最小)

现在,乘这让一个随机数[R

0 <=(X-最小)* r <=(最大-最小)* r

现在,让min添加回方程

最小<=最小+(X-最小)* r <=最小+(最大-最小)* r

现在,让我们选择一个得出r的函数,使其满足我们的方程范围为[min,max]。仅当0 <= r <= 1时才有可能

好。现在,r即[0,1] 的范围与Math.random()函数的结果非常相似。是不是

Math.random()函数返回范围为[0,1)的浮点伪随机数;即从0(含)到1(不含)但不包括

例如,

情况r = 0

min+ 0 *(max- min)= 分钟

情况r = 1

min+1 *(max- min)= 最大值

使用Math.random的随机情况0 <= r <1

min+ r *(max- min)= X,其中X的范围为min <= X < max

上面的结果X是一个随机数字。但是由于Math.random(),我们的左边界是包含在内的,而右边界是排斥的。为了包括我们的右边界,我们将右边界增加1并下限结果。

function generateRandomInteger(min, max) {
  return Math.floor(min + Math.random()*(max + 1 - min))
}

获取随机数

generateRandomInteger(-20, 20);



24
var x = 6; // can be any number
var rand = Math.floor(Math.random()*x) + 1;

2
确实。我忘了兰特是0。固定它。
ryebr3ad 2011年

3
那是伪代码的一部分……有人可能会认为它是真实的,然后尝试那样使用它。
重力男孩

35
@gravityboy你在说什么?如果某人不能用数字代替[选择数字...],那么他们可能不适合作为程序员。
ryebr3ad

7
@ ryebr3ad -1!用javascript而不是伪代码表示,也不是所有的读者都是熟练的程序员。许多是初学者!
2012年

3
@ ryebr3ad:我有一位同事正在向实习生讲授他们需要支持的数据库环境。他告诉他们从表中选择所有内容,然后他们开始在SQL查询编辑器中编写“从...中选择所有内容”。他的反应与您相同。
Ellesedil 2015年

22

jsfiddle:https ://jsfiddle.net/cyGwf/477/

随机整数:要获取min和之间的随机整数max,请使用以下代码

function getRandomInteger(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

随机浮点数:要获取介于min和之间的随机浮点数max,请使用以下代码

function getRandomFloat(min, max) {
  return Math.random() * (max - min) + min;
}

参考:https : //developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/random


14

数学不是我的强项,但是我一直在从事一个项目,我需要在正负之间生成许多随机数。

function randomBetween(min, max) {
    if (min < 0) {
        return min + Math.random() * (Math.abs(min)+max);
    }else {
        return min + Math.random() * max;
    }
}

例如

randomBetween(-10,15)//or..
randomBetween(10,20)//or...
randomBetween(-200,-100)

当然,您也可以添加一些验证,以确保除了数字以外不要使用其他任何方法。还要确保最小值始终小于或等于最大值。


5
这是完全错误的。min + Math.random() * max将为您提供介于min和min + max之间的数字,这不是您想要的。的第一个分支if是正确的,但可以简化为return min + Math.random() * (max - min),这是正确的解决方案,而与min是正数还是负数无关(请参见其他答案)。另外,请记住,如果您不需要分数,则仍需要对结果取底。
阿维什(Avish)

10

我写了更灵活的函数,它可以为您提供随机数,而不仅仅是整数。

function rand(min,max,interval)
{
    if (typeof(interval)==='undefined') interval = 1;
    var r = Math.floor(Math.random()*(max-min+interval)/interval);
    return r*interval+min;
}

var a = rand(0,10); //can be 0, 1, 2 (...) 9, 10
var b = rand(4,6,0.1); //can be 4.0, 4.1, 4.2 (...) 5.9, 6.0

固定版本。


这不是一个好的解决方案,因为它不能将最小值设为零。请参阅@Lior的答案。
塞巴斯蒂安2015年

当然,它的最小值为零。你试过了吗?没有任何理由可能不起作用。间隔为0并不奇怪(间隔= 0?...)。
ElChupacabra

我多次运行此函数,最小值为零,但从未在输出中获得零。还是我不够幸运……
塞巴斯蒂安2015年

你是对的。“ + interval”在错误的位置。请现在进行测试。有时候console.log给我0.300000004而不是3 * 0.1之类的0.3的奇怪东西并不完全是0.3。
ElChupacabra


7

尽管有许多答案,但结果几乎相同。我想补充一下我的答案并解释其工作原理。因为重要的是要了解其工作原理,而不是复制粘贴一行代码。生成随机数只不过是简单的数学运算。

码:

function getR(lower, upper) {

  var percent = (Math.random() * 100);
  // this will return number between 0-99 because Math.random returns decimal number from 0-0.9929292 something like that
  //now you have a percentage, use it find out the number between your INTERVAL :upper-lower 
  var num = ((percent * (upper - lower) / 100));
  //num will now have a number that falls in your INTERVAL simple maths
  num += lower;
  //add lower to make it fall in your INTERVAL
  //but num is still in decimal
  //use Math.floor>downward to its nearest integer you won't get upper value ever
  //use Math.ceil>upward to its nearest integer upper value is possible
  //Math.round>to its nearest integer 2.4>2 2.5>3   both lower and upper value possible
  console.log(Math.floor(num), Math.ceil(num), Math.round(num));
}

6

我正在搜索用TypeScript编写的随机数生成器,并在阅读所有答案后编写了此代码,希望它适用于TypeScript编码人员。

    Rand(min: number, max: number): number {
        return (Math.random() * (max - min + 1) | 0) + min;
    }   

5

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的标准number类型可以表示的最大公共整数大小。(BigInt如果需要更大的范围,可以将其修改为使用s。)无论选择哪个范围,被拒绝的生成值的分数将始终小于0.5,因此预期的拒绝数将始终小于1.0且通常接近0.0;您无需担心它会永远循环。

const randomInteger = (min, max) => {
  const range = max - min;
  const maxGeneratedValue = 0xFFFFFFFF;
  const possibleResultValues = range + 1;
  const possibleGeneratedValues = maxGeneratedValue + 1;
  const remainder = possibleGeneratedValues % possibleResultValues;
  const maxUnbiased = maxGeneratedValue - remainder;

  if (!Number.isInteger(min) || !Number.isInteger(max) ||
       max > Number.MAX_SAFE_INTEGER || min < Number.MIN_SAFE_INTEGER) {
    throw new Error('Arguments must be safe integers.');
  } else if (range > maxGeneratedValue) {
    throw new Error(`Range of ${range} (from ${min} to ${max}) > ${maxGeneratedValue}.`);
  } else if (max < min) {
    throw new Error(`max (${max}) must be >= min (${min}).`);
  } else if (min === max) {
    return min;
  } 

  let generated;
  do {
    generated = crypto.getRandomValues(new Uint32Array(1))[0];
  } while (generated > maxUnbiased);

  return min + (generated % possibleResultValues);
};

console.log(randomInteger(-8, 8));          // -2
console.log(randomInteger(0, 0));           // 0
console.log(randomInteger(0, 0xFFFFFFFF));  // 944450079
console.log(randomInteger(-1, 0xFFFFFFFF));
// Error: Range of 4294967296 covering -1 to 4294967295 is > 4294967295.
console.log(new Array(12).fill().map(n => randomInteger(8, 12)));
// [11, 8, 8, 11, 10, 8, 8, 12, 12, 12, 9, 9]


现在,这就是我所说的过度杀伤力。
2xSamurai,

2
@ 2xSamurai在这里,我更新了答案以解释为什么您可能需要它以及它如何工作。那个更好吗?:P
Jeremy Banks

如果您希望获得加密安全且均匀分布的随机数,这根本不是个大问题。很难生成满足这些要求的随机数。很好的答案,@ JeremyBanks。
thomaskonrad

4

float根据int@Francisc的答案中的版本添加具有固定精度的版本:

function randomFloatFromInterval (min, max, fractionDigits) {
  const fractionMultiplier = Math.pow(10, fractionDigits)
  return Math.round(
    (Math.random() * (max - min) + min) * fractionMultiplier,
  ) / fractionMultiplier
}

所以:

randomFloatFromInterval(1,3,4) // => 2.2679, 1.509, 1.8863, 2.9741, ...

对于int答案

randomFloatFromInterval(1,3,0) // => 1, 2, 3


1

这应该工作:

const getRandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min

1

我发现了一种使用ES6默认参数执行此操作的好方法。这很漂亮,因为它允许一个参数或两个参数。这里是:

function random(n, b = 0) {
    return Math.random() * (b-n) + n;
}

1

这大约晚了九年,但是randojs.com使这变得简单:

rando(1, 6)

您只需要将其添加到html文档的头部,就可以轻松地随机执行几乎任何您想做的事情。来自数组的随机值,随机jquery元素,对象的随机属性,甚至在需要时防止重复。

<script src="https://randojs.com/1.0.0.js"></script>

为什么要添加一个依赖项来执行已经是单行的事情?对在JS社区中添加库的痴迷是疯狂的
Daniel Cooke

更容易阅读和记住。我同意了
亚伦Plocharczyk,

1

这对我有用,并产生类似Python的random.randint标准库函数的值:


function randint(min, max) {
   return Math.round((Math.random() * Math.abs(max - min)) + min);
}

console.log("Random integer: " + randint(-5, 5));


1

基本上像骰子一样返回1-6,

return Math.round(Math.random() * 5 + 1);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.