在特定范围内用javascript生成随机整数?

 2019-04-29 

Generating random whole numbers in JavaScript in a specific range?

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


Mozilla开发者网络页面上有一些示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * 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。所以我们有这样一个时间间隔:

1
[0 .................................... 1)

现在,我们想要一个介于EDOCX1(含)和EDOCX1(不含)之间的数字:

1
2
[0 .................................... 1)
[min .................................. max)

我们可以使用Math.random来获取[最小,最大]间隔中的对应项。但是,首先,我们应该从第二个区间减去min,稍微考虑一下这个问题:

1
2
[0 .................................... 1)
[min - min ............................ max - min)

这给出:

1
2
[0 .................................... 1)
[0 .................................... max - min)

我们现在可以应用Math.random,然后计算相应的值。让我们选择一个随机数:

1
2
3
4
5
6
                Math.random()
                    |
[0 .................................... 1)
[0 .................................... max - min)
                    |
                    x (what we need)

因此,为了找到x,我们会:

1
x = Math.random() * (max - min);

别忘了把min加回去,这样我们就可以得到[min,max]区间内的一个数字:

1
x = Math.random() * (max - min) + min;

这是MDN的第一个函数。第二个函数返回minmax之间的整数,两者都包含在内。

现在,为了得到整数,可以使用roundceilfloor

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

1
2
3
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,您的分布非常均匀。

1
2
3
4
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结果。


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


数学,随机化()

从Mozilla Developer Network文档中:

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

Math.floor(Math.random() * (max - min + 1)) + min;

有用的例子:

1
2
3
4
5
6
7
8
9
10
11
// 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;

1
2
3
4
5
function getRandomizer(bottom, top) {
    return function() {
        return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
    }
}

用途:

1
2
3
4
5
6
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。

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

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

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

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

Math.floor将数字向下舍入到最接近的整数。现在我们有了0top-bottom之间的所有整数。1看起来很混乱,但是它必须在那里,因为我们总是取整,所以没有它就永远无法到达顶部数字。我们生成的随机小数需要在0(1+top-bottom)的范围内,这样我们就可以四舍五入,得到0top-bottom范围内的int。

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

上一个示例中的代码给出了一个范围为0top-bottom的整数,因此我们现在需要做的就是将bottom添加到该结果中,以得到范围为bottomtop的整数。D

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


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

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

返回介于1和100之间的随机数:

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


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

如果您使用的是underline.js,则可以使用

1
_.random(min, max)


其他答案不能解释01的完全合理的参数。相反,您应该使用round而不是ceilfloor

1
2
3
4
5
6
7
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


如果需要介于0和max之间的变量,可以使用:

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


使用计算机程序生成随机数后,如果选取的数字是初始数字的一部分或全部,则仍将其视为随机数。但如果它被改变了,数学家就不会接受它为随机数,他们可以称之为有偏数。但是,如果你正在开发一个简单任务的程序,那么这不是一个需要考虑的问题。但是,如果您正在开发一个程序来为有价值的东西(如彩票程序或赌博游戏)生成随机数,那么如果您不考虑上述情况,您的程序将被管理层拒绝。

所以对于这类人,我的建议是:

使用Math.random()生成一个随机数。

1
2
Now for [0,10) ==>  n*10 (i.e. one digit) and for[10,100) ==> n*100 (i.e. two digits) and so on. Here squire bracket indicates that boundary is inclusive and round bracket indicates boundary is exclusive.
Then remove the rest after the decimal point. (i.e. get floor) - using Math.floor(), this can be done.

如果你知道如何读取随机数表来选择一个随机数,你知道上面的过程(乘以1,10,100等等)并没有违反我在开头提到的过程(因为它只改变小数点的位置)。

学习下面的例子,并根据您的需要进行开发。

如果你需要一个样本[0,9],那么N*10的楼层就是你的答案;如果需要[0,99],那么N*100的楼层就是你的答案,以此类推。

现在让我们进入你的角色:

您询问了特定范围内的数字。(在这种情况下,您在该范围内有偏见。-通过掷骰子从[1,6]中取一个数字,那么你将偏向于[1,6],但如果并且仅当骰子是无偏的,那么它仍然是随机的。)

所以考虑你的范围=>[78247]范围的元素数=247-78+1=170;(因为两个边界都包含在内)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*Mthod 1:*/
    var i = 78, j = 247, k = 170, a = [], b = [], c, d, e, f, l = 0;
    for(; i <= j; i++){ a.push(i); }
    while(l < 170){
        c = Math.random()*100; c = Math.floor(c);
        d = Math.random()*100; d = Math.floor(d);
        b.push(a[c]); e = c + d;
        if((b.length != k) && (e < k)){  b.push(a[e]); }
        l = b.length;
    }
    console.log('Method 1:');
    console.log(b);
/*Method 2:*/

    var a, b, c, d = [], l = 0;
    while(l < 170){
        a = Math.random()*100; a = Math.floor(a);
        b = Math.random()*100; b = Math.floor(b);
        c = a + b;
        if(c <= 247 || c >= 78){ d.push(c); }else{ d.push(a); }
        l = d.length;
    }
    console.log('Method 2:');
    console.log(d);

注意:在方法一中,我首先创建了一个包含您需要的数字的数组,然后将它们随机放入另一个数组中。在方法2中,随机生成数字并检查这些数字是否在您需要的范围内。然后把它放到一个数组中。在这里,我生成了两个随机数,并使用它们的总数通过最小化获得有用数的失败率来最大化程序的速度。然而,增加生成的数字也会带来一些偏差。所以我推荐我的第一种方法,在特定范围内生成随机数。

在这两种方法中,您的控制台都将显示结果。(按chrome中的f12打开控制台)


下面是用JavaScript实现随机类的ms-dotnet-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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;
}());

用途:

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

对于具有范围的随机整数,请尝试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function random(minimum, maximum) {
  var bool = true;

  while (bool) {
    var number = (Math.floor(Math.random() * maximum + 1) + minimum);
    if (number > 20) {
      bool = true;
    } else {
      bool = false;
    }
  }

  return number;
}

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

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

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

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

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

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

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

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

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

从最小值中去掉0.5的原因是,仅使用最小值就可以得到一个大于最大值的整数。通过从最小值中去掉0.5,基本上可以防止最大值被四舍五入。

希望有帮助。


使用以下代码,您可以在给定范围内生成随机数数组,而无需重复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function genRandomNumber(how_many_number,min,max) {

            // parameters
            // how_many_number : how many numbers you want to generate. For example it is 5.
            // min(inclusive) : minimum/low value of a range. it must be any positive integer but less than max. i.e 4
            // max(inclusive) : maximun value of a range. it must be any positive integer. i.e 50
            // return type: array

            var random_number = [];
            for (var i = 0; i < how_many_number; i++) {
                var gen_num = parseInt((Math.random() * (max-min+1)) + min);
                do {
                    var is_exist = random_number.indexOf(gen_num);
                    if (is_exist >= 0) {
                        gen_num = parseInt((Math.random() * (max-min+1)) + min);
                    }
                    else {
                        random_number.push(gen_num);
                        is_exist = -2;
                    }
                }
                while (is_exist > -1);
            }
            document.getElementById('box').innerHTML = random_number;
        }

我知道这个问题已经回答了,但我的回答可以帮助别人。

我在W3学校找到了这个简单的方法:

1
Math.floor((Math.random() * max) + min);

希望这能帮助别人。


最低和最高之间的随机整数:

1
2
3
4
5
6
function randomRange(l,h){
  var range = (h-l);
  var random = Math.floor(Math.random()*range);
  if (random === 0){random+=1;}
  return l+random;
}

不是最优雅的解决方案。但有点快。


这是我用来生成随机数的方法。

1
2
3
4
function random(high,low) {
    high++;
    return Math.floor((Math.random())*(high-low))+low;
}

我们执行high++是因为Math.random()生成了一个介于0(含)和1(不含)之间的随机数被排除,这意味着在执行任何数学运算之前,我们必须先增加一个。然后,我们从高位减去低位,得到要生成的最高数字-低位,然后+低位,使高位恢复正常,使最低的数字至少低位。然后返回结果编号

random(7,3)可以返回3,4,5,6, or 7


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    <!DOCTYPE html>
<html>
    <head>
            <meta charset="utf-8" />
    </head>
    <body>
       
            /*

                assuming that window.crypto.getRandomValues is available
                the real range would be fron 0 to 1,998 instead of 0 to 2,000
                See javascript documentation for explanation
                https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues
            */

            var array = new Uint8Array(2);
            window.crypto.getRandomValues(array);
            console.log(array[0] + array[1]);

       
    </body>
</html>

uint8数组创建一个最多可填充3位数字的数组,最多可填充999位数字。这个代码很短。


下面是一个javascript函数的示例,该函数可以生成任意指定长度的随机数,而无需使用math.random():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    function genRandom(length)
    {
     const t1 = new Date().getMilliseconds();
     var min ="1",max ="9";
     var result;
     var numLength = length;
     if (numLength != 0)
     {
        for (var i = 1; i < numLength; i++)
        {
           min = min.toString() +"0";
           max = max.toString() +"9";
        }
     }
     else
     {
        min = 0;
        max = 0;
        return;
     }

      for (var i = min; i <= max; i++)
      {
           //Empty Loop
      }

      const t2 = new Date().getMilliseconds();
      console.log(t2);
      result = ((max - min)*t1)/t2;
      console.log(result);
      return result;
    }


1
2
3
4
5
6
7
8
9
10
11
function getRandomInt(lower, upper)
{
    //to create an even sample distribution
    return Math.floor(lower + (Math.random() * (upper - lower + 1)));

    //to produce an uneven sample distribution
    //return Math.round(lower + (Math.random() * (upper - lower)));

    //to exclude the max value from the possible values
    //return Math.floor(lower + (Math.random() * (upper - lower)));
}

要测试此函数以及此函数的变体,请将下面的HTML/javascript保存到一个文件中,然后用浏览器打开。代码将生成一个显示一百万个函数调用分布的图表。代码还将记录边缘情况,因此如果函数生成的值大于最大值或小于最小值,您将知道它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<html>
    <head>
        <script type="text/javascript">
        function getRandomInt(lower, upper)
        {
            //to create an even sample distribution
            return Math.floor(lower + (Math.random() * (upper - lower + 1)));

            //to produce an uneven sample distribution
            //return Math.round(lower + (Math.random() * (upper - lower)));

            //to exclude the max value from the possible values
            //return Math.floor(lower + (Math.random() * (upper - lower)));
        }

        var min = -5;
        var max = 5;

        var array = new Array();

        for(var i = 0; i <= (max - min) + 2; i++) {
          array.push(0);
        }

        for(var i = 0; i < 1000000; i++) {
            var random = getRandomInt(min, max);
            array[random - min + 1]++;
        }

        var maxSample = 0;
        for(var i = 0; i < max - min; i++) {
            maxSample = Math.max(maxSample, array[i]);
        }

        //create a bar graph to show the sample distribution
        var maxHeight = 500;
        for(var i = 0; i <= (max - min) + 2; i++) {
            var sampleHeight = (array[i]/maxSample) * maxHeight;

            document.write('<span style="display:inline-block;color:'+(sampleHeight == 0 ? 'black' : 'white')+';background-color:black;height:'+sampleHeight+'px">&nbsp;[' + (i + min - 1) + ']:&nbsp;'+array[i]+'</span>&nbsp;&nbsp;');
        }
        document.write('<hr/>');
       
    </head>
    <body>

    </body>
</html>

这是我对一个范围内的随机数的处理,就像我想得到一个从基到指数范围内的随机数一样。例如,base=10,exponent=2,给出从0到100的随机数,理想情况下,依此类推。

如果它有助于使用它,这里是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// get random number within provided base + exponent
// by Goran Biljetina --> 2012

function isEmpty(value){
    return (typeof value ==="undefined" || value === null);
}
var numSeq = new Array();
function add(num,seq){
    var toAdd = new Object();
     toAdd.num = num;
     toAdd.seq = seq;
     numSeq[numSeq.length] = toAdd;
}
function fillNumSeq (num,seq){
    var n;
    for(i=0;i<=seq;i++){
        n = Math.pow(num,i);
        add(n,i);
    }
}
function getRandNum(base,exp){
    if (isEmpty(base)){
        console.log("Specify value for base parameter");
    }
    if (isEmpty(exp)){
        console.log("Specify value for exponent parameter");
    }
    fillNumSeq(base,exp);
    var emax;
    var eseq;
    var nseed;
    var nspan;
    emax = (numSeq.length);
    eseq = Math.floor(Math.random()*emax)+1;
    nseed = numSeq[eseq].num;
    nspan = Math.floor((Math.random())*(Math.random()*nseed))+1;
    return Math.floor(Math.random()*nspan)+1;
}

console.log(getRandNum(10,20),numSeq);
//testing:
//getRandNum(-10,20);
//console.log(getRandNum(-10,20),numSeq);
//console.log(numSeq);

我做了这个函数,它考虑了诸如min、max、exclude(要排除的整数列表)和seed(如果您想要一个种子随机生成器)等选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
get_random_int = function(args={})
{
    let def_args =
    {
        min: 0,
        max: 1,
        exclude: false,
        seed: Math.random
    }

    args = Object.assign(def_args, args)

    let num = Math.floor(args.seed() * (args.max - args.min + 1) + args.min)

    if(args.exclude)
    {
        let diff = args.max - args.min
        let n = num

        for(let i=0; i<diff*2; i++)
        {
            if(args.exclude.includes(n))
            {
                if(n + 1 <= args.max)
                {
                    n += 1
                }

                else
                {
                    n = args.min
                }
            }

            else
            {
                num = n
                break
            }
        }
    }

    return num
}

它的用途如下:

1
2
3
4
5
6
7
8
9
let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1,
        exclude: [3, 6, 5],
        seed: my_seed_function
    }
)

或者更简单地说:

1
2
3
4
5
6
7
let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1
    }
)

然后你可以做:

1
let item = some_list[n]

注册表:https://gist.github.com/madprops/757deb000bdec25776d5036dae58ee6e


这可以处理生成最多20位的唯一随机数

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var generatedNumbers = [];

function generateRandomNumber(precision) { // precision --> number precision in integer
    if (precision <= 20) {
        var randomNum = Math.round(Math.random().toFixed(precision) * Math.pow(10, precision));
        if (generatedNumbers.indexOf(randomNum) > -1) {
            if (generatedNumbers.length == Math.pow(10, precision))
                return"Generated all values with this precision";
                return generateRandomNumber(precision);
        } else {
            generatedNumbers.push(randomNum);
            return randomNum;
        }
    } else
       return"Number Precision shoould not exceed 20";
}
generateRandomNumber(1);

enter image description here

杰西德


/*编写一个名为randUpTo的函数,该函数接受一个数字并返回0和那个数字之间的随机整数?*/

1
2
3
var randUpTo = function(num) {
    return Math.floor(Math.random() * (num - 1) + 0);
};

/*编写一个名为randBetween的函数,它接受两个数字表示一个范围并返回这两个范围之间的随机整数数字。*/

1
2
3
var randBetween = function (min, max) {
    return Math.floor(Math.random() * (max - min - 1)) + min;
};

/*编写一个名为randFromTill的函数,它接受两个数字表示一个范围并返回一个介于min(含min)之间的随机数和max(独占)。*/

1
2
3
var randFromTill = function (min, max) {
    return Math.random() * (max - min) + min;
};

/*编写一个名为randFromTo的函数,它接受两个数字表示一个范围并返回一个介于min(含min)之间的随机整数最大值(含)*/

1
2
3
var randFromTo = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};


Math.random()快速且适用于许多目的,但如果您需要密码安全值(它不安全),或者如果您需要完全一致的无偏分布的整数(其他答案中使用的乘法方法产生某些值的频率略高于其他方法),则不适用。

在这种情况下,我们可以使用crypto.getRandomValues()生成安全的整数,并拒绝任何生成的不能统一映射到目标范围的值。这将变慢,但除非生成的值数量非常大,否则它不应该很重要。

为了澄清有偏分布的问题,考虑这样一种情况,我们希望生成1到5之间的值,但是我们有一个随机数生成器,它生成1到16之间的值(4位值)。我们希望有相同数量的生成值映射到每个输出值,但是16不能平均除以5:它留下1的余数。因此,我们需要拒绝可能生成的值中的1个,并且只有当我们得到可以统一映射到目标范围的15个较小的值之一时才能继续。我们的行为可能看起来像这样的伪代码:

1
2
3
4
5
6
7
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类型表示的最大的通用整数大小。(如果需要更大的范围,可以修改为使用BigInts。)无论选择的范围是什么,被拒绝的生成值的分数都将始终小于0.5,因此预期的拒绝数将始终小于1.0,通常接近0.0;您不必永远担心它的循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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]


替代方案:

1
2
3
4
5
6
7
8
9
let makeGuess = function(guess){
    let min = 1;
    let max = 5;  
    let randomNumber = Math.floor(Math.random() * (max - min + 1)) + min

    return guess === randomNumber;

}
console.log(makeGuess(1));

我想知道,经过足够多的运行后,分配会是怎样的对于这样一个随机化函数。

还要检查在不同的浏览器中,这个分布是否或多或少是相同的。

下面是一个要运行的代码片段。按下按钮前可以更改号码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function getRandomNumberInRange(Min, Max) {
    return Math.floor(Math.random() * (Max - Min + 1)) + Min;
}

function printDictAsTable(dict){
   let htmlstr ="<table border=1><tr><th>Number</th><th>Count</th></tr>";
   
   let sortedKeys = Object.keys(dict).sort(function(a,b){return a-b});

   for (let i=0; i<sortedKeys.length; i++) {
     let key = sortedKeys[i];
     htmlstr +="<tr><td>"+ key +" </td><td>" + dict[key] +" </td></tr>";
   }
   htmlstr +="</table>";
   document.getElementById("tableContainer").innerHTML = htmlstr;
}

function loopRandomAndPrint(){
    let min = Number(document.getElementById("randomMinLimit").value);
    let max = Number(document.getElementById("randomMaxLimit").value);
    if (max < min){let temp = max; max = min; min = temp;}
    let loopTotal = Number(document.getElementById("loopLimit").value);
    let dict = {};
   
    for(i = min; i <= max; ++i){
        dict[i] = 0;
    }

    for(i = 0; i < loopTotal; i++){
        let num = getRandomNumberInRange(min, max);
        dict[num] = dict[num] + 1;
    }
   
    printDictAsTable(dict);
}

loopRandomAndPrint();
1
2
3
4
5
6
7
8
9
10
11
<p>
Min  : <input type="number" id="randomMinLimit" value=4>
</p>
<p>
Max  : <input type="number" id="randomMaxLimit" value=8>
</p>
<p>
Loops: <input type="number" id="loopLimit" value=1000>
</p>
<button type="button" onclick="loopRandomAndPrint()">
Loop random function and show </button>


生成五位数随机数

1
2
3
 function rn(min, max){
    return Math.floor(Math.random() * min + max);
 }

例子

1
 rn(2342, 9999)

希望它有帮助