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

怎样才能在 JavaScript 两个指定的变量之间的随机整数,例如x = 4y = 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( Math.random()之间的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 的第一个功能。第二个,返回介于minmax之间(包括两个端点)的整数。

现在要获取整数,可以使用roundceilfloor

您可以使用Math.round(Math.random() * (max - min)) + min ,但这会产生不均匀的分布。 minmax滚动率只有大约一半:

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

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

Math.random()

Mozilla开发人员网络文档中:

// Returns a random integer between min (include) and max (include)

Math.floor(Math.random() * (max - min + 1)) + 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;
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.
}

分解:

我们正在返回一个函数(从函数编程中借用),该函数在被调用时将返回一个在值bottomtop之间的随机整数(包括首尾)。我们说 “包含” 是因为我们希望在可以返回的数字范围内同时包含底部和顶部。这样, getRandomizer( 1, 6 )将返回 1、2、3、4、5 或 6。

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

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

Math.random()返回一个介于 0 和 1 之间的随机双Math.random() ,如果将它乘以 1 加上topbottom之间的差,我们将在01+ba之间得到一个双1+ba

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

Math.floor将数字四舍五入到最接近的整数。现在我们有了0top-bottom之间的所有整数。 1 看起来令人困惑,但是它必须存在,因为我们一直在四舍五入,因此没有它,就不会真正达到最高数字。我们生成的随机小数必须在0(1+top-bottom)的范围内,因此我们可以四舍五入并获得在0top-bottom范围内的 int

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

前面示例中的代码为我们提供了一个0top-bottom范围内的整数,因此,我们现在要做的就是在结果中添加bottom以获得一个范围在bottomtop包括bottom范围内的整数。 :D


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

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

如果您使用的是Underscore.js ,则可以选择使用

_.random(min, max)

返回 1 到 10 之间的随机数:

Math.floor((Math.random()*10) + 1);

返回 1 到 100 之间的随机数:

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

如果您需要 0 到 max 之间的变量,则可以使用:

Math.floor(Math.random() *  max);

其他答案并没有说明01的完全合理的参数。相反,您应该使用ceil round 而不是 ceilfloor

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

这是 javascript - 中的 Random 类的 MS DotNet 实现

var Random = (function () {
function Random(Seed) {
    if (!Seed) {
        Seed = this.milliseconds();
    }
    this.SeedArray = [];
    for (var i = 0; i < 56; i++)
        this.SeedArray.push(0);
    var num = (Seed == -2147483648) ? 2147483647 : Math.abs(Seed);
    var num2 = 161803398 - num;
    this.SeedArray[55] = num2;
    var num3 = 1;
    for (var i_1 = 1; i_1 < 55; i_1++) {
        var num4 = 21 * i_1 % 55;
        this.SeedArray[num4] = num3;
        num3 = num2 - num3;
        if (num3 < 0) {
            num3 += 2147483647;
        }
        num2 = this.SeedArray[num4];
    }
    for (var j = 1; j < 5; j++) {
        for (var k = 1; k < 56; k++) {
            this.SeedArray[k] -= this.SeedArray[1 + (k + 30) % 55];
            if (this.SeedArray[k] < 0) {
                this.SeedArray[k] += 2147483647;
            }
        }
    }
    this.inext = 0;
    this.inextp = 21;
    Seed = 1;
}
Random.prototype.milliseconds = function () {
    var str = new Date().valueOf().toString();
    return parseInt(str.substr(str.length - 6));
};
Random.prototype.InternalSample = function () {
    var num = this.inext;
    var num2 = this.inextp;
    if (++num >= 56) {
        num = 1;
    }
    if (++num2 >= 56) {
        num2 = 1;
    }
    var num3 = this.SeedArray[num] - this.SeedArray[num2];
    if (num3 == 2147483647) {
        num3--;
    }
    if (num3 < 0) {
        num3 += 2147483647;
    }
    this.SeedArray[num] = num3;
    this.inext = num;
    this.inextp = num2;
    return num3;
};
Random.prototype.Sample = function () {
    return this.InternalSample() * 4.6566128752457969E-10;
};
Random.prototype.GetSampleForLargeRange = function () {
    var num = this.InternalSample();
    var flag = this.InternalSample() % 2 == 0;
    if (flag) {
        num = -num;
    }
    var num2 = num;
    num2 += 2147483646.0;
    return num2 / 4294967293.0;
};
Random.prototype.Next = function (minValue, maxValue) {
    if (!minValue && !maxValue)
        return this.InternalSample();
    var num = maxValue - minValue;
    if (num <= 2147483647) {
        return parseInt((this.Sample() * num + minValue).toFixed(0));
    }
    return this.GetSampleForLargeRange() * num + minValue;
};
Random.prototype.NextDouble = function () {
    return this.Sample();
};
Random.prototype.NextBytes = function (buffer) {
    for (var i = 0; i < buffer.length; i++) {
        buffer[i] = this.InternalSample() % 256;
    }
};
return Random;
}());

采用:

var r = new Random();
        var nextInt = r.Next(1, 100); //returns an integer between range
        var nextDbl = r.NextDouble(); //returns a random decimal

使用此功能获取给定范围之间的随机数

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