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


1954

如何在JavaScript中的两个指定变量之间生成随机整数,例如x = 4y = 8并输出以下任何内容4, 5, 6, 7, 8


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

9
附带说明:对于那些使用npm并正在寻找快速,可靠和现成的解决方案的人来说,有一个lodash.random可以很容易地以很小的占用空间来要求(它将仅导入方法本身,而不是整个lodash)。
大雄

Answers:


3830

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()返回Number介于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回去,这样我们就可以在[min,max)间隔中得到一个数字:

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

这是MDN的第一个功能。第二个,返回介于min和之间的整数max,包括两者。

现在,用于获取整数,您可以使用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结果。


10
之所以这样做,是因为它正在调用floor,它会四舍五入。
乔什·斯托多拉

4
@ thezachperson31您可以使用round,但可以同时使用,min并且max只有一半的机会像其他数字一样滚动。您也可以减去一个并取ceil。但是max,由于[0,1)间隔,这使得号码滚动的机会最少。
Christoph

12
如果有人要测试此方法的分布,我已经创建了一个JSFiddle:jsfiddle.net/F9UTG/1
ahren 2013年

8
@JackFrost是的,是的。您不傻,只是在学习:)
Ionuț G. Stan

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

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

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

11
@IsmaelMiguel使用二进制运算符(x << 0x | 0~~x),而不是Math.floor()转换x小得多的范围分成两补比Number.MAX_SAFE_INTEGER(2³²⁻¹与2⁵³),因此你必须谨慎使用!
le_m

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

@bluejayke因为657348096152(二进制1001100100001100111111111111100001000011000)具有40位,而按位算术则使用32位。如果执行此操作,657348096152|0则会得到218099864(二进制的1100111111111111000010011000)。
Ismael Miguel

1
这是一个聪明的答案。在内部将范围设为[min,max + 1)实际上会达到[min,max]包含两者的期望结果。谢谢!:)
Mladen B.19年

134

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


56
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。

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

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

Math.random()返回0和1之间的随机双,如果我们用它乘间一个加的区别topbottom,我们会得到之间的双某处01+b-a

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

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

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

上一个示例中的代码为我们提供了一个范围为0和的整数top-bottom,因此我们现在要做的就是将bottom结果加到该范围内bottomtop包括此范围)的整数。:D


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


1
我意识到这大约是2½年之后,但是使用输入1和6,您的函数将返回值1,2,3,4和5,但不会返回值6,就好像它是“包含”值一样。
一些

9
@some,可能会更糟,我是2½年+ 1天后^^
ajax333221

+1,我测试了您的代码,它似乎创建了正确的值。用于处理可能在代码中重复很多的固定方案的创意结构。
克里斯

为什么为此在函数中有一个函数?
Alph.Dev

1
@ Alph.Dev将使用随机数生成器的逻辑与确切确定使用哪种随机数分布的逻辑分离。当使用随机数生成器的代码接受它作为参数(始终返回新随机数的0参数函数)时,它可以与任何类型的随机数生成器一起使用。
Gordon Gustafson

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

如果您正在使用Underscore.js,则可以选择使用

_.random(min, max)

1
下划线实际上提供了_.uniqueId()可以调用客户端模型的功能。
obfk 2015年

使用二进制运算符(x << 0x | 0~~x的),而不是Math.floor()转换x成两个互补与更小的范围比Number.MAX_SAFE_INTEGER(2³²⁻¹与2⁵³),因此你必须谨慎使用!
le_m

30

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

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

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

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

您的“介于两者之间”是包含性的还是排他性的?即是[1,10],[1,10),(1,10]还是(1,10)?
evandrix 15/11/27

1
它是部分包容性的:[1,*)
Ivan Z

函数末尾需要+ 1是什么?我猜它完美地工作了。
Shachi

18

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

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

是max包含或排除>?

2
使用Math.floor max的@Tree是唯一的。如果希望max包含所有内容,则可以使用Math.round。
路加

14

其他答案不占的完全合理的参数01。相反,你应该使用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

1
您的回答是正确的,但我认为您的示例是错误的console.log(randomNumber(5,6)); # 9 6 6 5 7 7。9和7是否介于5和6之间?............您应该纠正它或解释..
萨钦(Sachin)2015年

12

这是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

MS DotNet Random类受Ms-RSL许可,这意味着它已受版权保护。因此,在使用此衍生代码时,请务必小心,因为它可能构成侵犯版权案件的基础。
JohannesB

12

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

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

10

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

因此,对于那些人,这是我的建议:

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

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],但当且仅当骰子无偏差时,它仍然是随机的)

因此,请考虑您的范围==> [78,247]范围内的元素数= 247-78 + 1 = 170; (因为两个边界都是包容性的。

/*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);

注意:在方法一中,首先我创建了一个包含所需数字的数组,然后将它们随机放入另一个数组中。在方法二中,随机生成数字并检查它们是否在所需范围内。然后将其放入数组。在这里,我生成了两个随机数,并使用它们的总数来通过最大程度地降低获得有用数的失败率来最大化程序的速度。但是,将生成的数字相加也会带来一些偏差。因此,我建议我使用第一种方法来生成特定范围内的随机数。

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


3
“随机”不一定表示“均匀分布”。“有偏见”并不意味着“非随机”。从概率分布中得出的随机均值。
syzygy 2015年

6
几乎不能说出这个答案要说的是什么。但是,如果您需要随机数来进行彩票号和赌博等用途。首先,您可能不应该在客户端上生成它们。其次,您需要加密安全的随机数生成器,并且提供的算法还不够。重复调用random不会使结果“更加随机”。作者似乎担心偏见,但并未提供防止这种偏见的好方法。实际上,提供的其他简短答案会产生无偏的随机数(假设底层随机生成器是无偏的)。
杰夫·沃克

@JeffWalkerCodeRanger我认为他的意思是,使用“正常”算法[即Math.floor(Math.random() * (6 - 1 + 1) + 1)],数字1和6的滚动次数必然比2、3、4和5少。
oldboy

10

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

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;
}

8
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保存到文件中,然后使用浏览器打开。该代码将产生一个图表,显示一百万个函数调用的分布。该代码还将记录边缘情况,因此,如果函数产生的值大于最大值或小于最小值,则将提示您。

<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/>');
        </script>
    </head>
    <body>

    </body>
</html>

7

要获得介于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,实际上可以防止最大值被四舍五入。

希望能有所帮助。


如果您排除了0,那么就有意义,那么就无需将范围从0向下舍入到0.5。
ILMostro_7 '16

7

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

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;
        }

7

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

我在W3Schools上找到了这个简单的方法:

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

希望这会帮助某人。


1
Math.floor((Math.random()* 1)+ 0); 总是给0
madprops'Apr 29'17

1
@madprops因为最大数量是排他的。要获得0或1,应将2设置为最大数字。
NutCracker

1
或者您只需在调用此方法的函数中添加+1
Pietro Coelho

6

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

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

不是最优雅的解决方案..但是很快。


5

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

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

我们之所以执行,high++是因为Math.random()生成的随机数介于0(含)和1(不含)之间。被排除的那个意味着我们必须在执行任何数学运算之前将高值加1。然后,我们从高点减去低点,从而给我们生成的最大数-从低到高,再到+低,使高点恢复正常,使最小数至少为低。然后我们返回结果数

random(7,3) 可能会回来 3,4,5,6, or 7


2
正如high只使用一次一样,您最好使用high-low+1而不是使用单独的增量语句。同样,大多数用户希望low参数排在第一位。
克里斯·沃尔什

4
    <!DOCTYPE html>
<html>
    <head>
            <meta charset="utf-8" />
    </head>
    <body>
        <script>
            /*

                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]);

        </script>
    </body>
</html>

Uint8Array创建一个由最多3位数字填充的数组,该数字最多为999。此代码非常短。


4

这是一个javascript函数的示例,可以在不使用Math.random()的情况下生成任意指定长度的随机数

    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;
    }

t1 / t2总是非常接近1。因此,当重复调用函数时,函数返回相同的数字。jsbin.com/xogufacera/edit?js,console
Sunil BN

检查jsbin网址。您将自己看到输出
Sunil BN

当长度在4到10之间时(如我在机器上测试过的),它的效果很好,因为常量T1和T2的值应具有适当的距离。
Nilesh Pawar

3

这是我对某个范围内的随机数的看法,因为我想获得一个从基数到指数范围内的随机数。例如,base = 10,指数= 2,给出一个从0到100的随机数,理想情况下,依此类推。

如果它有助于使用它,则为:

// 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);

3

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]



1

您可以使用此代码段,

let randomNumber = function(first,second){
let number = Math.floor(Math.random()*Math.floor(second));
while(number<first){

    number = Math.floor(Math.random()*Math.floor(second));
}
return number;
}

1
这里有不必要的重复行。请使用do - while代替while
JaviMarzán19年

1

Ionuț G. Stan给出了一个很好的答案,但这对我来说太复杂了。因此,我在https://teamtreehouse.com/community/mathfloor-mathrandom-max-min-1-min-explanation找到了一个更简单的解释。 Jason Anello的。

注意:在阅读Jason的说明之前,您应该知道的唯一重要的事情是“截断”的定义。他在描述时使用了这个术语Math.floor()。牛津词典将“截断”定义为:

剪掉顶部或末端以缩短(东西)。


0

最多可以处理20位UNIQUE随机数

JS

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);

在此处输入图片说明

JsFiddle


我赞成这仅仅是因为。
泰勒·阿克莱

1
@TaylorAckley此答案未解决问题。
RomainValeri

0

/ *写一个函数randUpTo,它接受一个数字并返回一个介于0和该数字之间的随机整数?* /

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

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

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

/ *编写一个函数randFromTill,该函数接受两个代表范围的数字,并返回介于min(含)和max(不含)之间的随机数。* /

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

/ *编写一个函数randFromTo,该函数接受表示范围的两个数字并返回介于min(含)和max(含)之间的随机整数* /

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

1
美丽,您还可以注意到randBetween是(独家)(独家)吗?
pfdint

0

我制作此函数时考虑了最小值,最大值,排除(要排除的整数列表)和种子(如果需要种子随机生成器)的选项。

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
}

可以像这样使用:

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

或更简单地说:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1
    }
)

然后,您可以执行以下操作:

let item = some_list[n]

要点:https : //gist.github.com/madprops/757deb000bdec25776d5036dae58ee6e


0
  • random(min,max)生成一个介于min(含)和max(不含)之间的随机数
  • Math.floor将数字四舍五入到最接近的整数

    function generateRandomInteger (min, max) { 
        return Math.floor(random(min,max)) 
    }`

因此,要生成一个介于4到8之间的随机整数,请使用以下参数调用上述函数:

generateRandomInteger (4,9)

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.