Generating random whole numbers in JavaScript in a specific range?

zacharyliu Source

How can I generate a random whole number between two specified variables in Javascript, e.g. x = 4 and y = 8 would output any of 4, 5, 6, 7, 8?

javascriptrandominteger

Answers

answered 9 years ago Ionuț G. Stan #1

There are some examples on the Mozilla Developer Network page:

/**
 * 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)
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

Here's the logic behind it. It's a simple rule of three:

Math.random() returns a Number between 0 (inclusive) and 1 (exclusive). So we have an interval like this:

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

Now, we'd like a number between min (inclusive) and max (exclusive):

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

We can use the Math.random to get the correspondent in the [min, max) interval. But, first we should factor a little bit the problem by subtracting min from the second interval:

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

This gives:

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

We may now apply Math.random and then calculate the correspondent. Let's choose a random number:

                Math.random()
                    |
[0 .................................... 1)
[0 .................................... max - min)
                    |
                    x (what we need)

So, in order to find x, we would do:

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

Don't forget to add min back, so that we get a number in the [min, max) interval:

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

That was the first function from MDN. The second one, returns an integer between min and max, both inclusive.

Now for getting integers, you could use round, ceil or floor.

You could use Math.round(Math.random() * (max - min)) + min, this however gives a non-even distribution. Both, min and max only have approximately half the chance to roll:

min...min+0.5...min+1...min+1.5   ...    max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘   ← Math.round()
   min          min+1                          max

With max excluded from the interval, it has an even less chance to roll than min.

With Math.floor(Math.random() * (max - min +1)) + min you have a perfectly even distribution.

min.... min+1... min+2 ... max-1... max.... max+1 (is excluded from interval)
|        |        |         |        |        |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘   ← Math.floor()
   min     min+1               max-1    max

You can't use ceil() and -1 in that equation because max now had a slightly less chance to roll, but you can roll the (unwanted) min-1 result too.

answered 9 years ago Gordon Gustafson #2

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

usage:

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

breakdown:

We are returning a function (borrowing from functional programming) that when called, will return a random integer between the the values bottom and top, inclusive. We say 'inclusive' because we want to include both bottom and top in the range of numbers that can be returned. This way, getRandomizer( 1, 6 ) will return either 1, 2, 3, 4, 5, or 6.

(bottom is lower number, top is greater number)

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

Math.random() returns a random double between 0 and 1, and if we multiply it by one plus the difference between top and bottom, we'll get a double somewhere between 0 and 1+b-a.

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

Math.floor rounds the number down to the nearest integer. So we now have all the integers between 0 and top-bottom. The 1 looks confusing, but it needs to be there because we are always rounding down, so the top number will never actually be reached without it. The random decimal we generate needs to be in the range 0 to (1+top-bottom) so we can round down and get an int in the range 0 to top-bottom

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

The code in the previous example gave us an integer in the range 0 and top-bottom, so all we need to do now is add bottom to that result to get an integer in the range bottom and top inclusive. :D


NOTE: If you pass in a non-integer value or the greater number first you'll get undesirable behavior, but unless anyone requests it I am not going to delve into the argument checking code as its rather far from the intent of the original question.

answered 9 years ago Chris #3

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

To test this function, and variations of this function, save the below HTML/JavaScript to a file and open with a browser. The code will produce a graph showing the distribution of one million function calls. The code will also record the edge cases, so if the the function produces a value greater than the max, or less than the min, you.will.know.about.it.

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

answered 9 years ago Darin Dimitrov #4

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

answered 6 years ago user1764199 #5

For a random integer with a range, try:

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

answered 5 years ago Codler #6

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

Alternative if you are using Underscore.js you can use

_.random(min, max)

answered 5 years ago Janaka R Rajapaksha #7

After generating a random number using a computer program, it is still consider as a random number if the picked number is a part or the full one of the initial one. But if it was changed, then mathematicians are not accept it as a random number and they can call it a biased number. But if you are developing a program for a simple task, this will not be a case to consider. But if you are developing a program to generate a random number for a valuable stuff such as lottery program, or gambling game, then your program will be rejected by the management if you are not consider about the above case.

So for those kind of people, here is my suggestion:

Generate a random number using Math.random().(say this 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.

If you know how to read random number table to pick a random number, you know above process(multiplying by 1, 10, 100 and so on) is not violates the one that I was mentioned at the beginning.( Because it changes only the place of the decimal point.)

Study the following example and develop it to your needs.

If you need a sample [0,9] then floor of n*10 is your answer and if need [0,99] then floor of n*100 is your answer and so on.

Now let enter into your role:

You've asked numbers among specific range. (In this case you are biased among that range. - By taking a number from [1,6] by roll a die, then you are biased into [1,6] but still it is a random if and only if die is unbiased.)

So consider your range ==> [78, 247] number of elements of the range = 247 - 78 + 1 = 170; (since both the boundaries are inclusive.

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

Note: In method one, first I created an array which contains numbers that you need and then randomly put them into another array. In method two, generate numbers randomly and check those are in the range that you need. Then put it into an array. Here I generated two random numbers and used total of them to maximize the speed of the program by minimizing the failure rate that obtaining a useful number. However adding generated numbers will also give some biassness. So I would recommend my first method to generate random numbers within a specific range.

In both methods, your console will show the result.(Press f12 in Chrome to open the console)

answered 5 years ago Learner.js #8

To get a random number say between 1 and 6, first do:

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

This multiplies a random number by 6 and then adds 0.5 to it. Next round the number to a positive integer by doing:

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

This round the number to the nearest whole number.

Or to make it more understandable do this:

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

In general the code for doing this using variables is:

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

The reason for taking away 0.5 from the minimum value is because using the minimum value alone would allow you to get an integer that was one more than your maximum value. By taking away 0.5 from the minimum value you are essentially preventing the maximum value from being rounded up.

Hope that helps.

answered 5 years ago brooklynsweb #9

Random whole number between lowest and highest:

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

Not the most elegant solution.. but something quick.

answered 4 years ago Prasobh.K #10

Return a random number between 1 and 10:

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

Return a random number between 1 and 100:

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

answered 4 years ago Starkers #11

The other answers don't account for the perfectly reasonable parameters of 0 and 1. Instead you should use the round instead of ceil or floor:

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

answered 3 years ago Travis #12

Here's what I use to generate random numbers.

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

We do execute high++ becauseMath.random() generates a random number between 0, (inclusive), and 1(exclusive) The one being excluded, means we must increase the high by one before executing any math. We then subtract low from high, giving us the highest number to generate - low, then +low, bringing high back to normal, and making the lowest number atleast low. then we return the resulting number

random(7,3) could return 3,4,5,6, or 7

answered 3 years ago Lior Elrom #13

Math.random()

From the Mozilla Developer Network documentation:

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

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

Useful examples:

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

answered 3 years ago Yusuf #14

Using following code you can generate array of random numbers, without repeating, in a given range.

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

answered 3 years ago Goran B. #15

this is my take on a random number in a range, as in I wanted to get a random number within a range of base to exponent. e.g. base = 10, exponent = 2, gives a random number from 0 to 100, ideally, and so on.

if it helps use it, here it is:

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

answered 3 years ago happy #16

    <!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 create a array filled with a number up to 3 digits which would be a maximum of 999. This code is very short.

answered 2 years ago PeMaCN #17

I know this question is already answered but my answer could help someone.

I found this simple method on W3Schools:

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

Hope this would help someone.

answered 2 years ago Nofi #18

This can handle generating upto 20 digit UNIQUE random number

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

enter image description here

JsFiddle

answered 2 years ago Ariful Islam #19

Here is the MS DotNet Implementation of Random class in javascript-

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

Use:

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

answered 10 months ago Nilesh Pawar #20

Hey Guys I have created a javascript function same as Math.random() using which we can generate random number of any specified length. Without using any Math.random function.

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

answered 9 months ago Stanislav Vincent #21

If you need variable betwee 0 and max you can use:

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

answered 2 weeks ago Prakhar Mittal #22

/* Write a function called randUpTo that accepts a number and returns a random whole number between 0 and that number? */

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

/* Write a function called randBetween that accepts two numbers representing a range and returns a random whole number between those two numbers. */

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

/* Write a function called randFromTill that accepts two numbers representing a range and returns a random number between min (inclusive) and max (exclusive). */

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

/* Write a function called randFromTo that accepts two numbers representing a range and returns a random integer between min (inclusive) and max (inclusive) */

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

comments powered by Disqus