Problem
In JavaScript, how can I generate random whole integers between two specified variables, e.g., x = 4 and y = 8 would produce any of 4, 5, 6, 7, or 8?
Asked by zacharyliu
Solution #1
On the Mozilla Developer Network page, there are various examples:
/**
* 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;
}
This is the reasoning behind it. It’s a straightforward three-step process:
Math.random() returns a number ranging from 0 (inclusive) to 1 (exclusive) (exclusive). As a result, we have something like this:
[0 .................................... 1)
Now we need a number that falls somewhere between min (inclusive) and max (exclusive):
[0 .................................... 1)
[min .................................. max)
To retrieve the corresponding in the [min, max) interval, we can use Math.random. However, we should first factor the problem a little by subtracting min from the second interval:
[0 .................................... 1)
[min - min ............................ max - min)
This gives:
[0 .................................... 1)
[0 .................................... max - min)
We can now use Math.random to generate a random number and then calculate the corresponding. Let’s pick a number at random.
Math.random()
|
[0 .................................... 1)
[0 .................................... max - min)
|
x (what we need)
So, to find x, we’d execute the following:
x = Math.random() * (max - min);
Don’t forget to subtract min to get a number in the [min, max) range:
x = Math.random() * (max - min) + min;
That was the first MDN function. The second produces an integer that is between min and max, inclusive.
You can now use round, ceil, or floor to retrieve integers.
You could use Math.round(Math.random() * (max – min)) + min to get an even distribution, however this will give you a non-even distribution. Both min and max only have around a half-chance of rolling:
min...min+0.5...min+1...min+1.5 ... max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max
It has an even lower likelihood of rolling than min when max is omitted from the interval.
You can get a perfectly even distribution by using 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
Because max now has a somewhat lower chance of rolling, you can’t utilize ceil() and -1 in that equation, but you can roll the (unwanted) min-1 result.
Answered by Ionuț G. Stan
Solution #2
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
Answered by Darin Dimitrov
Solution #3
Between min (included) and max (included), returns an integer random number:
function randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Alternatively, any number between min (included) and max (excluded):
function randomNumber(min, max) {
return Math.random() * (max - min) + min;
}
Useful examples (integers):
// 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;
** And, as Mozilla reminds us, it’s always good to be reminded:
Answered by Lior Elrom
Solution #4
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’re returning a function (borrowing from functional programming) that will return a random integer between bottom and top, inclusive, when called. We use ‘inclusive’ because we want the range of numbers returned to encompass both the bottom and top. getRandomizer(1, 6) will now return one of the following values: 1, 2, 3, 4, 5, or 6.
(lower number at bottom, higher number at top)
Math.random() * ( 1 + top - bottom )
Math. random() gives a random double between 0 and 1, which we may multiply by one plus the top-bottom difference to get a double between 0 and 1+b-a.
Math.floor( Math.random() * ( 1 + top - bottom ) )
The number is rounded down to the nearest integer with Math.floor. So now we have all the integers in the range of 0 to top-bottom. The 1 may appear perplexing, but it is necessary since we are continually rounding down, and without it, the top number will never be reached. We need a random decimal in the range of 0 to (1+top-bottom) so that we can round down and acquire an int in the range of 0 to top-bottom.
Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom
We already have an integer in the range 0 to top-bottom thanks to the code in the previous example; all we have to do now is add bottom to that result to get an integer in the range bottom to top inclusive.
NOTE: If you send in a non-integer value or the higher number first, you’ll get unexpected results, but unless someone requests it, I’m not going to go into the argument checking code because it’s so far off from the original question’s intent.
Answered by Gordon Gustafson
Solution #5
Return a number between 1 and 10 at random.
Math.floor((Math.random()*10) + 1);
Pick a number between 1 and 100 at random:
Math.floor((Math.random()*100) + 1)
Answered by Prasobh.Kollattu
Post is based on https://stackoverflow.com/questions/1527803/generating-random-whole-numbers-in-javascript-in-a-specific-range