首页
 

通知公告

在 JavaScript 中生成特定范围内的随机整数

来源:欧亿体育点击:时间:2024-01-28 01:03

问:

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

答1:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

Mozilla Developer Network 页面上有一些示例:

/**
 * 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... min+2 ... max-1... max.... max+1 (is excluded from interval)
|        |        |         |        |        |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘   ← Math.floor()
   min     min+1               max-1    max

您不能在该等式中使用 ceil() 和 -1,因为 max 现在滚动的机会稍少,但您也可以滚动(不需要的)min-1 结果。

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

它这样做只是因为它调用了 floor,它向下取整。

@thezachperson31 您可以使用 round,但是 min 和 max 都只有一半的机会像其他数字一样滚动。您也可以减去一个并取 ceil。然而,由于 [0,1) 间隔,这使得 max 数字滚动的机会最小。

如果有人想测试此方法的分布,我创建了一个 JSFiddle:jsfiddle.net/F9UTG/1

@JackFrost 是的,没错。你不傻,你只是在学习:)

这个问题很老,但是理解这个答案让我花了太多时间哦,我认为在下一个 JavaScript 版本上扩展 math.random 会很有用

答2:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;

我知道这是一个非常古老的答案,但使用 (Math.random() * (maximum - minimum + 1) ) << 0 更快。

@IsmaelMiguel 使用二元运算符(x << 0、x | 0、~~x)而不是 Math.floor() 将 x 转换为范围比 Number.MAX_SAFE_INTEGER 小得多的二补码(2³²⁻¹ vs. 2⁵³),因此你必须谨慎使用它!

@IsmaelMiguel 哟,我刚刚在控制台中尝试了你的方法,随机得到一个负值! Math.randRange = (最小值,最大值) => (Math.random() * (最大值 - 最小值 + 1) ) << 0 Math.randRange(2,657348096152) -1407373159

@bluejayke因为657348096152(二进制1001100100001100111111111111000010011000)有40位,而按位算术使用32位。如果你执行 657348096152|0,你会得到 218099864(二进制的 1100111111111111000010011000)。

这是一个聪明的答案。使范围在内部 [min, max+1) 实际上实现了 [min, max] 包含两者的期望结果。谢谢! :)

答3:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

数学随机()

返回介于 min (included) 和 max (included) 之间的 integer random number:

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

或在最小值(包括)和最大值(不包括)之间的any random number:

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.ceil,那么 +1 可以省掉

答4:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

利用:

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

(‘bottom’ 是较小的数字,而 ‘top’ 是较大的数字)

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

Math.random() 返回 0 和 1 之间的随机双精度数,如果我们将它乘以 1 加上 top 和 bottom 之间的差,我们将在 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 内的整数包括的。