如何在JavaScript中的两个指定变量之间生成随机整数,例如x=4和y=8将输出4、5、6、7、8中的任意一个?


当前回答

其他答案没有考虑到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

其他回答

Use:

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。我们说“包含”是因为我们希望将底部和顶部都包含在可返回的数字范围内。这样,getRandomizer(1,6)将返回1、2、3、4、5或6。

(“底部”是较低的数字,“顶部”是较大的数字)

Math.random() * ( 1 + top - bottom )

Math.random()返回一个介于0和1之间的随机双精度,如果我们将其乘以1加上顶部和底部之间的差值,我们将得到一个介于介于0和1+b-a之间的双精度。

Math.floor( Math.random() * ( 1 + top - bottom ) )

Math.floor将数字向下舍入到最接近的整数。所以我们现在有了0和上下之间的所有整数。1看起来很令人困惑,但它需要存在,因为我们总是向下舍入,因此没有它就永远无法到达顶部数字。我们生成的随机小数需要在0到(1+上下)的范围内,这样我们就可以向下舍入,得到0到上下的整数:

Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom

上一个示例中的代码为我们提供了一个范围为0和上下的整数,因此我们现在需要做的就是将底部添加到该结果中,以获得范围为底部和顶部(含)的整数D


注意:如果你先传入一个非整数值或更大的数字,你会得到不希望的行为,但除非有人要求,否则我不会深入研究参数检查代码,因为它与原始问题的意图相去甚远。

我想用一个例子来解释:

函数在JavaScript中生成5到25范围内的随机整数

概述:(i) 首先将其转换为范围-从0开始。(ii)然后将其转换为所需的范围(然后将非常易于完成)。

所以基本上,如果你想生成从5到25的随机整数,那么:

第一步:将其转换为范围-从0开始

从“max”和“min”中减去“lower/minimum number”。即

(5-5) - (25-5)

因此,范围将为:

0-20 ...正确的

第二步

现在,如果您希望两个数字都包含在范围内,即“0和20”,则公式为:

数学方程式:Math.floor((Math.random()*21))

一般公式:Math.floor((Math.random()*(max min+1)))

现在,如果我们将减去的/最小的数字(即5)添加到范围中,那么我们可以自动获得0到20的范围=>5到25

第三步

现在将减去的差值加在等式(即5)中,并将“Math.floor”添加到整个等式中:

数学方程式:Math.floor((Math.random()*21)+5)

一般公式:Math.floor((Math.random()*(max-min+1))+min)

因此,最终函数将是:

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

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的结果。

要获得一个介于1和6之间的随机数,首先执行以下操作:

0.5 + (Math.random() * ((6 - 1) + 1))

这会将一个随机数乘以6,然后再加上0.5。接下来,通过以下操作将该数舍入为正整数:

Math.round(0.5 + (Math.random() * ((6 - 1) + 1))

这将数字四舍五入到最接近的整数。

或者为了更容易理解,请执行以下操作:

var value = 0.5 + (Math.random() * ((6 - 1) + 1))
var roll = Math.round(value);
return roll;

通常,使用变量执行此操作的代码为:

var value = (Min - 0.5) + (Math.random() * ((Max - Min) + 1))
var roll = Math.round(value);
return roll;

从最小值中减去0.5的原因是,仅使用最小值可以获得比最大值多1的整数。通过从最小值中减去0.5,基本上防止了最大值被舍入。

以下是排字的解决方案

function getRandomInt(min:number, max:number):number {
    return min+Math.round(Math.random() * (max-min));
  }

  for(let i:number=0; i<100; i++){
  console.log(`${i+1} >> ${getRandomInt(1,6)}`)

  }