Generate random number between two numbers in JavaScript
Asked Answered
T

33

2536

Is there a way to generate a random number in a specified range with JavaScript ?

For example: a specified range from 1 to 6 were the random number could be either 1, 2, 3, 4, 5, or 6.

Turgot answered 10/2, 2011 at 16:41 Comment(17)
Math.floor( Math.random() * 7 )Paraffinic
Sure.. Math.floor(Math.random()*6+1)Paraffinic
Nabil Kadimi wrote an article on how to generate negative random numbers too.Radial
here is a useful gist: gist.github.com/kerimdzhanov/7529623Feola
why a solution like this Math.floor((Math.random()*10)+1); cannot work for you as specified here at w3schools.com/jsref/jsref_random.asp ..?Liquesce
This post describes several different ways of generating random values in JavaScriptHills
@Bondye there are systems that track previous randomly generated numbers. these systems do this to achieve an average. fr example. to make sure there is always a 10% chance of getting a number between 1 and 10. this method boils down to other questions for example. lottery syndrome- does someone else getting 5 lower my chances of getting 5Preterition
@Preterition In your way, if the range is 1-2, I can guess the next number. In most cases these pseudo-random numbers are not a problem, but some cases, you realy want random (for example in a lottery). You could use random.org, which uses atmospheric noise to generate random numbers. But notice that also this is not random, we just cannot (yet) guess the outcome of this noice.Defrock
@Bondye I agree.I think by fluffing the number of chances by expected number of attempts can help with the 1-2 scenario. for example. assuming it is a game where the coin flip leads to a favourable scenario. you can buffer it by putting something together like this [2, 1, 2, 1, 2, 1, 2, 1, 2, 1]. its a 50% chance to get 1 but the expected max number of attempts will be 10. each time a number is achieved remove it from the list increases chances for other entries. thanks for that random.org by the way.Preterition
After Bell inequalities violation, we can be sure, that random exists. agree with youShatzer
Why is this still not part of core javascript? I think we should band together and demand a dollar for each time we've had to google this.Marymarya
For anybody looking for a solution in Node.js, you can use crypto.randomInt(0,100) / 100Fiduciary
If the range is inclusive, try this: Math.round(Math.random() * (to - from)) + from);. You can generate (to - from) of these random numbers every 0.5 second using this function: function printNumbersTmOut(from, to){ time = 0; delay = 500; tmOut = setTimeout( function rangeCounter() { time = time + 1; if (from + time <= to) { setTimeout(rangeCounter, delay) } console.log(Math.round(Math.random() * (to - from)) + from); }, delay ) }Autoeroticism
I really dont undesrtand why many people are solving this simple task so wrong... what is your problem to select the difference between two numbers, include upper limit, select randomly a value within the limit, then floor it to be right integer, add to lower bound and here you go. Of course dont forget to be defensive and compare min with max if needed swap them, so formula becomes: Math.floor(Math.random(up - low + 1)) + low; What is your problem peoples?Crandall
See on page 2, or here: https://mcmap.net/q/40496/-generate-random-number-between-two-numbers-in-javascript. This simple function works in ANY cases (fully tested): Accepts negative numbers, Accepts floats (rounds them to the nearest integer), Accepts when the order of the 2 arguments is swapped (ie min>max). And the distribution of the results has been fully tested and is 100% correct.Ongoing
Does this answer your question? Generating random whole numbers in JavaScript in a specific rangeLovins
use this: const randomNumber = Math.floor(Math.random() * 6) + 1;Boatbill
F
2520

Important

The following code works only if the minimum value is `1`. It does not work for minimum values other than `1`.

If you wanted to get a random integer between 1 (and only 1) and 6, you would calculate:

    const rndInt = Math.floor(Math.random() * 6) + 1
    console.log(rndInt)

Where:

  • 1 is the start number
  • 6 is the number of possible results (1 + start (6) - end (1))
Foment answered 10/2, 2011 at 16:45 Comment(29)
While this would work, @Mike, it would be best to point out the more generic version as Francisc has it below :-).Rsfsr
-1. After Googling I found this question the title is ""Generate random value between two numbers in Javascript"." Won't work if the min value is 0Gaffer
Doesn't work if you want a number between two larger numbers eg. Math.floor(Math.random() * 900) + 700Blende
That only works if the minimum is 1. If the min is 2 and we still use Math.floor(Math.random() * 6) + 2 means that if Math.random() results into 0.99 our random value would be 7Disequilibrium
This code not good because, does not work with any number. @Ling code is the correct.Inactive
I just added a warning and a link to a JSFiddle I built showing the potential for unexpected results. Hopefully that'll help prevent people from being surprised.Somersomers
the correct way is Math.floor(Math.random() * (max-min)) + min so in this case it would be Math.floor(Math.random() * 5) + 1Spreadeagle
Technically, this would create a random number between 7 and one. like @Spreadeagle said, max-min.Genevagenevan
The question is "Generate random value between two numbers in JavaScript" ... the answer only relates to the example given in the question description, not to the mail question.Tosh
@Blende how can you justify saying this Math.floor(Math.random() * 900) + 700 won't work??? It gives the perfect (pseudo-random) results in the range [700,1599].Stewardess
@Stewardess I don't need to justify it, the OP wants a number between a range eg 1-6 which this answer works however if you want a different range .... say 700-900 this doesn't work as you pointed out it returns a number between 700-1599 which is not correct.Blende
@Blende I'm just nitpicking not correct vs not convenient you say it's not correct, when it is, based on the answer given, since the number of possible values in the range [700,900] is 201 therefore giving the statement Math.floor(Math.random()*201)+700; as per the answer given, which is correct.Stewardess
@Gaffer "Won't work if the min value is 0" if you know how to do subtraction then you will know how the answer is actually correct. [0,100]=>Math.floor(Math.random() * 101) + 0; as the answer states. See how 100-0+1==101, basic subtraction, just as is stated in the answer...Stewardess
There is no clarity here. The accepted answer has many upvotes, yet many knowledgeable people disagree. What is someone who doesn't already know the answer to make of this situation? Ins't the "zero" not working thing" a major problem?Primp
@Robin ??? "Zero not working"??? Do I have to say it again. If you want numbers starting at 0 and going to N. then the follow the answer and you get Math.floor(Math.random()*(N+1))+0; so how is this "not working"?Stewardess
ahem, Math.floor(Math.random() * 6 + 1). You have to include everything in Math.floor for it to work properly with other minimum values.Mariehamn
Why is this answer accepted, it produces false results. I made this jsfiddle to demonstrate, the result goes over the max number if min isn't 1 jsfiddle.net/45ste96f/1Rivas
That's not correct. My bad that I can't cancel my up-vote. Maybe the answer author can update it to something correct?Fathomless
This doesn't work in this case : Math.floor(Math.random() * 70) + 50, I need number between 50-70.Hibernaculum
This is not correct for two larger numbers Like: Math.floor(Math.random() * 1650) + 1400; The correct way is Math.floor(Math.random() * (max - min)) + min;Aeromedical
did a test on the above solution and the one from antitoxic. I created a function and ran them each 100 times. Got plenty of "undefined" returns. Those solutions have about a 30% chance of failing.Slowworm
I had to edit this answer to explain that the code works only if the minimum value is 1. Failing to specifying it was highly misleading and potentially dangerous.Vinegary
You can check how random it is by running this Array(100000).fill().map( () => Math.floor(Math.random() * 6)).reduce( (acc, i) => { acc[i]++; return acc } , [0,0,0,0,0,0]) in your enviroment. My result: [16609, 16664, 16769, 16450, 16708, 16800]Glasswork
The most accurate solution I've found: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }Fire
Math.floor(Math.random() * (max - min + 1)) + min;Crandall
Is there a reason to prefer Math.floor() instead of Math.ceil()? It seems to me, if we used Math.ceil() instead, we could avoid the +1Plinth
Actually, using Math.ceil() means you have to add min-1 instead of adding min, which makes using Math.floor() simpler in more general cases.Plinth
It is not correct.Crandall
See on page 2, or here: https://mcmap.net/q/40496/-generate-random-number-between-two-numbers-in-javascript. This simple function works in ANY cases (fully tested): Accepts negative numbers, Accepts floats (rounds them to the nearest integer), Accepts when the order of the 2 arguments is swapped (ie min>max). And the distribution of the results has been fully tested and is 100% correct.Ongoing
L
3328

function randomIntFromInterval(min, max) { // min and max included 
  return Math.floor(Math.random() * (max - min + 1) + min)
}

const rndInt = randomIntFromInterval(1, 6)
console.log(rndInt)

What it does "extra" is it allows random intervals that do not start with 1. So you can get a random number from 10 to 15 for example. Flexibility.

Ling answered 29/8, 2011 at 9:25 Comment(23)
this is also great because if someone doesn't include the to arg, the from arg doubles as the maxBegot
Just by reading, it seems to me this function spans beyond "to". If from=5 and to=5, I'm reading Math.floor(rand*(5-5+1)+5) = Math.floor(rand*(1)+5) = [5,6] instead of [5,5]. For from=5, to=6 I'm reading Math.floor(rand*(2)+5) = [5,7]. Am I mistaken? Is Math.Random() not both 0 and 1 inclusive?Shoveler
Hello. This is from MDN: Returns a floating-point, pseudo-random number in the range [0, 1) that is, from 0 (inclusive) up to but not including 1 (exclusive), which you can then scale to your desired range. (developer.mozilla.org/en-US/docs/JavaScript/Reference/…)Ling
Why would you add that +1? That makes the length of the interval larger that it is supposed to be, as Andreas Larsen pointed out. Here's the math: random=[0,1], length=to-from. Now span the interval to desired length: [0,1]*length = [0,length]. Then add offset: [0,length]+from = [from,length+from] = [from,to-from+from] = [from,to]. Example: from=4, to=7. [0,1]*(7-4) = [0,3] and so [0,3]+4 = [4,7].Cognizance
Read the above comment. Random is inside [0,1), not [0,1].Ling
Works great if the lower number is 0.Elongate
The lower number can be any number, not just 0.Ling
When you pass strings into it, it doesn't work. Made the edit.Alcinia
Yeah, you can just parseInt() from and to. It returns NaN for non numeric values so it's cool.Ling
Note that this solution is correct only if min and max are integers, otherwise you can get a result in the interval [min, ceil(max)]. I.e. you can get a result which is out of range because is higher than max.Tally
It's only for integers. It's easy to make it work with floats though.Ling
this function does not work correctly. if you put in min = 1 and max = 5 you just get 1, 2, 3 or 4. you never get the 5. if you give in min = 5 and max = 9 you still get 2, 3, 4, etc.Postglacial
That's not true, you must have made a mistake while testing this. I just did and it works as it should for 100,000 iterations.Ling
You can imagine a min and max or use the language's numeric limits.Ling
This is the same as @lior, with the missing bracket added. Is there some way this can appear at the top of the page as the correct answer by majority vote?Primp
This is what's used within Lodash and Underscore.Hungary
If I use this, however: return Math.floor(Math.random()*(max-min+1))+min, it works.Exhibitionist
You should remove the the +1 at the: (max - min + 1) part. It makes it less random. I tested this by creating a loop with 365 times generating a random number. This takes around 1.9 seconds. I do this loop over and over for at least 1 hour and found out that the number generates around 500 times above 0 and 50 times below. Random generating chances should be 50/50 but turns out its 1/999 this way. Remove the +1 and it seems to all work normal. Results: Both around 250 with a diffrence of around 20...Flambeau
The most accurate solution I've found: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }Fire
So in other words if I want to get random array index, it will be same as Math.floor(Math.random() * myArray.length) (because the ... length-1 + 0 +1) + 0 will be omited.Lanti
It won't work if min > max, cosider that case also.Crandall
See on page 2, or here: https://mcmap.net/q/40496/-generate-random-number-between-two-numbers-in-javascript. This simple function works in ANY cases (fully tested): Accepts negative numbers, Accepts floats (rounds them to the nearest integer), Accepts when the order of the 2 arguments is swapped (ie min>max). And the distribution of the results has been fully tested and is 100% correct.Ongoing
This is a good answer, but now multiple decades later, I haven't seen anyone attempt a simple explanation of why this works (maybe it's just innately obvious to everyone but me..), so I'll try: i.imgur.com/6NP85EI.pngAreopagite
F
2520

Important

The following code works only if the minimum value is `1`. It does not work for minimum values other than `1`.

If you wanted to get a random integer between 1 (and only 1) and 6, you would calculate:

    const rndInt = Math.floor(Math.random() * 6) + 1
    console.log(rndInt)

Where:

  • 1 is the start number
  • 6 is the number of possible results (1 + start (6) - end (1))
Foment answered 10/2, 2011 at 16:45 Comment(29)
While this would work, @Mike, it would be best to point out the more generic version as Francisc has it below :-).Rsfsr
-1. After Googling I found this question the title is ""Generate random value between two numbers in Javascript"." Won't work if the min value is 0Gaffer
Doesn't work if you want a number between two larger numbers eg. Math.floor(Math.random() * 900) + 700Blende
That only works if the minimum is 1. If the min is 2 and we still use Math.floor(Math.random() * 6) + 2 means that if Math.random() results into 0.99 our random value would be 7Disequilibrium
This code not good because, does not work with any number. @Ling code is the correct.Inactive
I just added a warning and a link to a JSFiddle I built showing the potential for unexpected results. Hopefully that'll help prevent people from being surprised.Somersomers
the correct way is Math.floor(Math.random() * (max-min)) + min so in this case it would be Math.floor(Math.random() * 5) + 1Spreadeagle
Technically, this would create a random number between 7 and one. like @Spreadeagle said, max-min.Genevagenevan
The question is "Generate random value between two numbers in JavaScript" ... the answer only relates to the example given in the question description, not to the mail question.Tosh
@Blende how can you justify saying this Math.floor(Math.random() * 900) + 700 won't work??? It gives the perfect (pseudo-random) results in the range [700,1599].Stewardess
@Stewardess I don't need to justify it, the OP wants a number between a range eg 1-6 which this answer works however if you want a different range .... say 700-900 this doesn't work as you pointed out it returns a number between 700-1599 which is not correct.Blende
@Blende I'm just nitpicking not correct vs not convenient you say it's not correct, when it is, based on the answer given, since the number of possible values in the range [700,900] is 201 therefore giving the statement Math.floor(Math.random()*201)+700; as per the answer given, which is correct.Stewardess
@Gaffer "Won't work if the min value is 0" if you know how to do subtraction then you will know how the answer is actually correct. [0,100]=>Math.floor(Math.random() * 101) + 0; as the answer states. See how 100-0+1==101, basic subtraction, just as is stated in the answer...Stewardess
There is no clarity here. The accepted answer has many upvotes, yet many knowledgeable people disagree. What is someone who doesn't already know the answer to make of this situation? Ins't the "zero" not working thing" a major problem?Primp
@Robin ??? "Zero not working"??? Do I have to say it again. If you want numbers starting at 0 and going to N. then the follow the answer and you get Math.floor(Math.random()*(N+1))+0; so how is this "not working"?Stewardess
ahem, Math.floor(Math.random() * 6 + 1). You have to include everything in Math.floor for it to work properly with other minimum values.Mariehamn
Why is this answer accepted, it produces false results. I made this jsfiddle to demonstrate, the result goes over the max number if min isn't 1 jsfiddle.net/45ste96f/1Rivas
That's not correct. My bad that I can't cancel my up-vote. Maybe the answer author can update it to something correct?Fathomless
This doesn't work in this case : Math.floor(Math.random() * 70) + 50, I need number between 50-70.Hibernaculum
This is not correct for two larger numbers Like: Math.floor(Math.random() * 1650) + 1400; The correct way is Math.floor(Math.random() * (max - min)) + min;Aeromedical
did a test on the above solution and the one from antitoxic. I created a function and ran them each 100 times. Got plenty of "undefined" returns. Those solutions have about a 30% chance of failing.Slowworm
I had to edit this answer to explain that the code works only if the minimum value is 1. Failing to specifying it was highly misleading and potentially dangerous.Vinegary
You can check how random it is by running this Array(100000).fill().map( () => Math.floor(Math.random() * 6)).reduce( (acc, i) => { acc[i]++; return acc } , [0,0,0,0,0,0]) in your enviroment. My result: [16609, 16664, 16769, 16450, 16708, 16800]Glasswork
The most accurate solution I've found: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }Fire
Math.floor(Math.random() * (max - min + 1)) + min;Crandall
Is there a reason to prefer Math.floor() instead of Math.ceil()? It seems to me, if we used Math.ceil() instead, we could avoid the +1Plinth
Actually, using Math.ceil() means you have to add min-1 instead of adding min, which makes using Math.floor() simpler in more general cases.Plinth
It is not correct.Crandall
See on page 2, or here: https://mcmap.net/q/40496/-generate-random-number-between-two-numbers-in-javascript. This simple function works in ANY cases (fully tested): Accepts negative numbers, Accepts floats (rounds them to the nearest integer), Accepts when the order of the 2 arguments is swapped (ie min>max). And the distribution of the results has been fully tested and is 100% correct.Ongoing
H
495

Math.random()

Returns an Integer Random Number between min (included) and max (included):

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

Returns Any Random Number between min (included) and max (not included):

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

Useful Examples (Integers):

// 0 -> 10
const rand1 = Math.floor(Math.random() * 11);

// 1 -> 10
const rand2 = Math.floor(Math.random() * 10) + 1;

// 5 -> 20
const rand3 = Math.floor(Math.random() * 16) + 5;

// -10 -> (-2)
const rand4 = Math.floor(Math.random() * 9) - 10;

console.log(rand1);
console.log(rand2);
console.log(rand3);
console.log(rand4);

** And always nice to be reminded (Mozilla):

Math.random() does not provide cryptographically secure random numbers. Do not use them for anything related to security. Use the Web Crypto API instead, and more precisely, the window.crypto.getRandomValues() method.

Huxley answered 11/6, 2014 at 0:23 Comment(7)
Something that confused me... the Math.floor(..) ensures that the number is an integer where Math.round(..) would give an uneven distribution. Ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Jaggers
I trust this answer. Can anyone give a link or clear explanation of why this works? Perhaps an example of how Math.round would give a bias, and why that means we have to use this rather complex-seeming formula?Primp
@Jaggers For a range of [1,2], there is 25% chance Math.random() would give you a number from one of these [0,0.49], [0.5,0.99], [1,1.49], [1.5,1.99]. Rounding those intervals would result in 0, 1, 1, 2 which is not an even distribution. Flooring them results in 0, 0, 1, 1.Behling
@shuji This is, among others, the correct answer. I just wanted to clarify why using Math.round over Math.floor would give different results.Behling
The most accurate solution I've found: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }Fire
It won't work if min > max, consider that case also.Crandall
@Crandall It was never supposed to check which of the two variables were smaller or larger in value. It's up to you to determine and pass it to the function.Huxley
G
114

TL;DR

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

To get the random number generateRandomInteger(-20, 20);

EXPLANATION BELOW

integer - A number which is not a fraction; a whole number

We need to get a random number , say X between min and max. X, min and max are all integers

i.e min <= X <= max

If we subtract min from the equation, this is equivalent to

0 <= (X - min) <= (max - min)

Now, lets multiply this with a random number r which is

0 <= (X - min) * r <= (max - min) * r

Now, lets add back min to the equation

min <= min + (X - min) * r <= min + (max - min) * r

For, any given X, the above equation satisfies only when r has range of [0,1] For any other values of r the above equation is unsatisfied.

Learn more about ranges [x,y] or (x,y) here

Our next step is to find a function which always results in a value which has a range of [0,1]

Now, the range of r i.e [0,1] is very similar to Math.random() function in Javascript. Isn't it?

The Math.random() function returns a floating-point, pseudo-random number in the range [0, 1); that is, from 0 (inclusive) up to but not including 1 (exclusive)

Random Function using Math.random() 0 <= r < 1

Notice that in Math.random() left bound is inclusive and the right bound is exclusive. This means min + (max - min) * r will evaluate to having a range from [min, max)

To include our right bound i.e [min,max] we increase the right bound by 1 and floor the result.

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

To get the random number

generateRandomInteger(-20, 20);

Gastropod answered 3/4, 2017 at 11:45 Comment(0)
D
103

Other solutions:

  • (Math.random() * 6 | 0) + 1
  • ~~(Math.random() * 6) + 1

Try online

Dunnite answered 9/11, 2011 at 10:8 Comment(8)
would you mind explaining (or giving references to) the ~~ sintaxis? I haven't seen it before! Elegant solution but hard to understand.Tsai
Double Tilde ~~a and Bitwise OR (a | 0) are faster ways to write Math.floor(a)Slain
a | 0 is also the fastest and most optimized way to convert a string to an integer. It only works with strings containing integers ("444" and "-444"), i.e. no floats/fractions. It yields a 0 for everything that fails. It is one of the main optimizations behind asm.js.Stopping
@Slain faster to write, but faster to execute as well?Molybdenum
According to the question I linked to, it seems that is it also faster.Slain
Note: if you are working with some really large numbers the double tilde is not going to work. Try ~~(Math.random() * (50000000000000 - 0 + 1)) + 0 and Math.floor(Math.random() * (50000000000000 - 0 + 1)) + 0Responsum
For ~~(Math.random() * 9) + 2 it printed 10.Mangrove
@TheWitness: This answer only works for min = 1; for other values, such as 2 to 9, you'd do ~~(Math.random() * (max - min + 1)) + min i.e. ~~(Math.random() * (9 - 2 + 1)) + 2 = ~~(Math.random() * 8) + 2.Hyo
D
34

Or, in Underscore

_.random(min, max)
Douzepers answered 3/10, 2014 at 1:52 Comment(0)
N
27
var x = 6; // can be any number
var rand = Math.floor(Math.random()*x) + 1;
Naval answered 10/2, 2011 at 16:46 Comment(0)
M
27

jsfiddle: https://jsfiddle.net/cyGwf/477/

Random Integer: to get a random integer between min and max, use the following code

function getRandomInteger(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

Random Floating Point Number: to get a random floating point number between min and max, use the following code

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

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

Marras answered 25/1, 2017 at 4:33 Comment(0)
A
23

Get a random integer between 0 and 400

let rand = Math.round(Math.random() * 400)

document.write(rand)

Get a random integer between 200 and 1500

let range = {min: 200, max: 1500}
let delta = range.max - range.min

const rand = Math.round(range.min + Math.random() * delta)

document.write(rand)

Using functions

function randBetween(min, max){
  let delta = max - min
  return Math.round(min + Math.random() * delta)
}

document.write(randBetween(10, 15));

// JavaScript ES6 arrow function

const randBetween = (min, max) => {
  let delta = max - min
  return Math.round(min + Math.random() * delta)
}

document.write(randBetween(10, 20))
Allonym answered 4/11, 2021 at 12:57 Comment(2)
Sorry, I took the wrong reason. But this solution doesn't provide uniform distributed random result. The min and max numbers get half of possibility of other numbers. For example, for a range of 1-3, you will have 50% possibility of getting 2.Animadvert
1 and 100 still get half of possibility. Before you apply rounding, the range is [1, 100). To get 1, the chance is 0.5/100=1/200, because only [1, 1.5) can be rounded to 1; to get 2, the chance is 1/100, because (1.5, 2.5] can be rounded to 2.Animadvert
R
18

Math is not my strong point, but I've been working on a project where I needed to generate a lot of random numbers between both positive and negative.

function randomBetween(min, max) {
    if (min < 0) {
        return min + Math.random() * (Math.abs(min)+max);
    }else {
        return min + Math.random() * max;
    }
}

E.g

randomBetween(-10,15)//or..
randomBetween(10,20)//or...
randomBetween(-200,-100)

Of course, you can also add some validation to make sure you don't do this with anything other than numbers. Also make sure that min is always less than or equal to max.

Raggedy answered 20/3, 2013 at 21:23 Comment(1)
This is simply wrong. min + Math.random() * max will give you numbers between min and min+max, which is not what you want. The first branch of the if is correct, but could be simplified to say return min + Math.random() * (max - min), which is the correct solution regardless of whether min is positive or negative (see the other answers). Also, keep in mind that you still need to floor the result if you don't want fractions.Viveca
M
14

ES6 / Arrow functions version based on Francis' code (i.e. the top answer):

const randomIntFromInterval = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
Maomaoism answered 4/1, 2021 at 0:40 Comment(0)
H
13

I wrote more flexible function which can give you random number but not only integer.

function rand(min,max,interval)
{
    if (typeof(interval)==='undefined') interval = 1;
    var r = Math.floor(Math.random()*(max-min+interval)/interval);
    return r*interval+min;
}

var a = rand(0,10); //can be 0, 1, 2 (...) 9, 10
var b = rand(4,6,0.1); //can be 4.0, 4.1, 4.2 (...) 5.9, 6.0

Fixed version.

Horoscopy answered 10/5, 2015 at 20:14 Comment(4)
This is not a good solution as it won't work with zero as min value. See @Lior's answer.Menhaden
Of course it works with zero as min value. Did you try? There is no reason why it might not work. It won't work with 0 as interval which isn't strange (interval = 0?...).Horoscopy
I ran multiple times this function with zero as min value and never obtained zero in the output. Or I'm not lucky enough...Menhaden
You are right. "+interval" was in wrong place. Test it now please. Strange thing that sometimes console.log gives me 0.300000004 instead of 0.3 like 3*0.1 wouldn't be exactly 0.3.Horoscopy
C
11

Math.random() is fast and suitable for many purposes, but it's not appropriate if you need cryptographically-secure values (it's not secure), or if you need integers from a completely uniform unbiased distribution (the multiplication approach used in others answers produces certain values slightly more often than others).

In such cases, we can use crypto.getRandomValues() to generate secure integers, and reject any generated values that we can't map uniformly into the target range. This will be slower, but it shouldn't be significant unless you're generating extremely large numbers of values.

To clarify the biased distribution concern, consider the case where we want to generate a value between 1 and 5, but we have a random number generator that produces values between 1 and 16 (a 4-bit value). We want to have the same number of generated values mapping to each output value, but 16 does not evenly divide by 5: it leaves a remainder of 1. So we need to reject 1 of the possible generated values, and only continue when we get one of the 15 lesser values that can be uniformly mapped into our target range. Our behaviour could look like this pseudocode:

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.

The following code uses similar logic, but generates a 32-bit integer instead, because that's the largest common integer size that can be represented by JavaScript's standard number type. (This could be modified to use BigInts if you need a larger range.) Regardless of the chosen range, the fraction of generated values that are rejected will always be less than 0.5, so the expected number of rejections will always be less than 1.0 and usually close to 0.0; you don't need to worry about it looping forever.

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]
Coffee answered 10/4, 2016 at 9:26 Comment(2)
@2xSamurai There, I updated the answer to explain why you might need this and how it works. Is that better? :PCoffee
It's not an overkill at all if you want cryptographically secure and uniformly distributed random numbers. Generating random numbers that meet those requirements is hard. Great answer, @JeremyBanks.Cubby
C
11

The top rated solution is not mathematically correct as same as comments under it -> Math.floor(Math.random() * 6) + 1.

Task: generate random number between 1 and 6.

Math.random() returns floating point number between 0 and 1 (like 0.344717274374 or 0.99341293123 for example), which we will use as a percentage, so Math.floor(Math.random() * 6) + 1 returns some percentage of 6 (max: 5, min: 0) and adds 1. The author got lucky that lower bound was 1., because percentage floor will "maximumly" return 5 which is less than 6 by 1, and that 1 will be added by lower bound 1.

The problems occurs when lower bound is greater than 1. For instance, Task: generate random between 2 and 6.

(following author's logic) Math.floor(Math.random() * 6) + 2, it is obviously seen that if we get 5 here -> Math.random() * 6 and then add 2, the outcome will be 7 which goes beyond the desired boundary of 6.

Another example, Task: generate random between 10 and 12.

(following author's logic) Math.floor(Math.random() * 12) + 10, (sorry for repeating) it is obvious that we are getting 0%-99% percent of number "12", which will go way beyond desired boundary of 12.

So, the correct logic is to take the difference between lower bound and upper bound add 1, and only then floor it (to substract 1, because Math.random() returns 0 - 0.99, so no way to get full upper bound, thats why we adding 1 to upper bound to get maximumly 99% of (upper bound + 1) and then we floor it to get rid of excess). Once we got the floored percentage of (difference + 1), we can add lower boundary to get the desired randomed number between 2 numbers.

The logic formula for that will be: Math.floor(Math.random() * ((up_boundary - low_boundary) + 1)) + 10.

P.s.: Even comments under the top-rated answer were incorrect, since people forgot to add 1 to the difference, meaning that they will never get the up boundary (yes it might be a case if they dont want to get it at all, but the requirenment was to include the upper boundary).

Crandall answered 7/2, 2021 at 0:34 Comment(1)
Math.floor(Math.random() * ((up_boundary - low_boundary) + 1)) + low_boundaryCrandall
O
10

Example

Return a random number between 1 and 10:

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

The result could be: 3

Try yourself: here

--

or using lodash / undescore:

_.random(min, max)

Docs: - lodash - undescore

Objectivity answered 30/4, 2016 at 18:5 Comment(2)
so you need 9 or 10 right? If yes: const randomNumber = Math.floor((Math.random() * 10) + 1) const nineOrTen = randomNumber % 2 === 0 ? 9 : 10Soave
This wont work, try with a example like 100 to 400Webb
V
9

I was searching random number generator written in TypeScript and I have written this after reading all of the answers, hope It would work for TypeScript coders.

    Rand(min: number, max: number): number {
        return (Math.random() * (max - min + 1) | 0) + min;
    }   
Vladikavkaz answered 7/9, 2014 at 14:14 Comment(0)
B
9

Crypto-strong

Crypto-strong random integer number in range [a,b] (assumption: a < b )

let rand= (a,b)=> a+(b-a+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0

console.log( rand(1,6) );
Burdelle answered 16/9, 2019 at 9:58 Comment(2)
That's a neat utilization of the crypto api - thumbs up! But I'm curious why you use 2**32 instead of 2**31 which would be the maximum value JS 32 bit integer.Raquel
@Raquel as far I know, JS not have "32bit integers" (type in console 2**32 - and js will show proper int value) - more here. We also have Uint32array -which means Unsigned Integer 32bit array)Nailbrush
F
8

Inspite of many answers and almost same result. I would like to add my answer and explain its working. Because it is important to understand its working rather than copy pasting one line code. Generating random numbers is nothing but simple maths.

CODE:

function getR(lower, upper) {

  var percent = (Math.random() * 100);
  // this will return number between 0-99 because Math.random returns decimal number from 0-0.9929292 something like that
  //now you have a percentage, use it find out the number between your INTERVAL :upper-lower 
  var num = ((percent * (upper - lower) / 100));
  //num will now have a number that falls in your INTERVAL simple maths
  num += lower;
  //add lower to make it fall in your INTERVAL
  //but num is still in decimal
  //use Math.floor>downward to its nearest integer you won't get upper value ever
  //use Math.ceil>upward to its nearest integer upper value is possible
  //Math.round>to its nearest integer 2.4>2 2.5>3   both lower and upper value possible
  console.log(Math.floor(num), Math.ceil(num), Math.round(num));
}
Fawcett answered 15/1, 2017 at 5:44 Comment(0)
B
6

to return 1-6 like a dice basically,

return Math.round(Math.random() * 5 + 1);
Bartle answered 30/9, 2019 at 11:20 Comment(1)
This isn't a good solution. round() compared to floor() will have a lower chance of throwing 1 and 6.Fraise
C
6

This function can generate a random integer number between (and including) min and max numbers:

function randomNumber(min, max) {
  if (min > max) {
    let temp = max;
    max = min;
    min = temp;
  }

  if (min <= 0) {
    return Math.floor(Math.random() * (max + Math.abs(min) + 1)) + min;
  } else {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }
}

Example:

randomNumber(-2, 3); // can be -2, -1, 0, 1, 2 and 3
randomNumber(-5, -2); // can be -5, -4, -3 and -2
randomNumber(0, 4); // can be 0, 1, 2, 3 and 4
randomNumber(4, 0); // can be 0, 1, 2, 3 and 4
Cookgeneral answered 26/8, 2020 at 21:23 Comment(4)
this will never roll 6 if max = 6 and min = 0Bond
@Bond I edited my answer, as Math.random() will never be 1.Cookgeneral
I think your answer is good in "theory" but it would be much better if you could clearly state in your answer if max = 6 would "include" the possibility of 6 or not, and if min = 1 would "include" the possibility of 1? This can be read very ambiguously, and might confuse people. Is it "max 6 - including 6" or "max 6 - not including 6"... Same for "min".Bond
I updated my answer to remove ambiguity and add the possibility of negative numbers.Cookgeneral
O
5

This simple function is handy and works in ANY cases (fully tested). Also, the distribution of the results has been fully tested and is 100% correct.

function randomInteger(pMin = 1, pMax = 1_000_000_000)
//Author: Axel Gauffre. 
//Here: https://mcmap.net/q/40496/-generate-random-number-between-two-numbers-in-javascript
//Inspired by: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values
//
//This function RETURNS A RANDOM INTEGER between pMin (INCLUDED) and pMax (INCLUDED).
//  - pMin and pMax should be integers.
//  - HOWEVER, if pMin and/or pMax are FLOATS, they will be ROUNDED to the NEAREST integer.
//  - NEGATIVE values ARE supported.
//  - The ORDER of the 2 arguments has NO consequence: If pMin > pMax, then pMin and pMax will simply be SWAPPED.
//  - If pMin is omitted, it will DEFAULT TO 1.
//  - If pMax is omitted, it will DEFAULT TO 1 BILLION.
//
//This function works in ANY cases (fully tested).
//Also, the distribution of the results has been fully tested and is 100% correct.
{
    pMin = Math.round(pMin);
    pMax = Math.round(pMax);
    if (pMax < pMin) { let t = pMin; pMin = pMax; pMax = t;}
    return Math.floor(Math.random() * (pMax+1 - pMin) + pMin);
}
Ongoing answered 1/12, 2022 at 4:31 Comment(0)
S
4

Adding float with fixed precision version based on the int version in @Francisc's answer:

function randomFloatFromInterval (min, max, fractionDigits) {
  const fractionMultiplier = Math.pow(10, fractionDigits)
  return Math.round(
    (Math.random() * (max - min) + min) * fractionMultiplier,
  ) / fractionMultiplier
}

so:

randomFloatFromInterval(1,3,4) // => 2.2679, 1.509, 1.8863, 2.9741, ...

and for int answer

randomFloatFromInterval(1,3,0) // => 1, 2, 3
Subtile answered 13/2, 2019 at 13:34 Comment(0)
E
4

Using random function, which can be reused.

function randomNum(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
randomNum(1, 6);
Enarthrosis answered 28/2, 2021 at 21:2 Comment(0)
L
4

Short Answer: It's achievable using a simple array.

you can alternate within array elements.

This solution works even if your values are not consecutive. Values don't even have to be a number.

let array = [1, 2, 3, 4, 5, 6];
const randomValue = array[Math.floor(Math.random() * array.length)];
Leeann answered 29/7, 2022 at 12:57 Comment(0)
I
3

This should work:

const getRandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min
Inhalation answered 16/7, 2019 at 12:47 Comment(0)
C
3

If the starting number is 1, as in your example (1-6), you can use Math.ceil() method instead of Math.floor().

Math.ceil(Math.random() * 6)

instead of

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

Let's not forget other useful Math methods.

Capitulum answered 16/5, 2021 at 18:43 Comment(0)
R
2

This is about nine years late, but randojs.com makes this a simple one-liner:

rando(1, 6)

You just need to add this to the head of your html document, and you can do pretty much whatever you want with randomness easily. Random values from arrays, random jquery elements, random properties from objects, and even preventing repetitions if needed.

<script src="https://randojs.com/1.0.0.js"></script>
Rheumatoid answered 2/12, 2019 at 2:39 Comment(0)
K
2

Try using:

function random(min, max) {
   return Math.round((Math.random() *( Math.abs(max - min))) + min);
}
console.log(random(1, 6));
Karakalpak answered 10/2, 2020 at 9:6 Comment(0)
U
1

I discovered a great new way to do this using ES6 default parameters. It is very nifty since it allows either one argument or two arguments. Here it is:

function random(n, b = 0) {
    return Math.random() * (b-n) + n;
}
Uri answered 17/7, 2019 at 17:0 Comment(0)
M
1

This works for me and produces values like Python's random.randint standard library function:


function randint(min, max) {
   return Math.round((Math.random() * Math.abs(max - min)) + min);
}

console.log("Random integer: " + randint(-5, 5));
Memoried answered 1/1, 2020 at 16:18 Comment(0)
M
0

for big number.

var min_num = 900;
var max_num = 1000;
while(true){
    
    let num_random = Math.random()* max_num;
    console.log('input : '+num_random);
    if(num_random >= min_num){
        console.log(Math.floor(num_random));
       break; 
    } else {
        console.log(':::'+Math.floor(num_random));
    }
}
Mortal answered 3/12, 2020 at 3:42 Comment(0)
C
0

If you want to cover negative and positive numbers, and make it safe then to use following:

JS solution:

function generateRangom(low, up) {
  const u = Math.max(low, up);
  const l = Math.min(low, up);
  const diff = u - l;
  const r = Math.floor(Math.random() * (diff + 1)); //'+1' because Math.random() returns 0..0.99, it does not include 'diff' value, so we do +1, so 'diff + 1' won't be included, but just 'diff' value will be.
  
  return l + r; //add the random number that was selected within distance between low and up to the lower limit.  
}

Java solution:

public static int generateRandom(int low, int up) {
        int l = Math.min(low, up);
        int u = Math.max(low, up);
        int diff = u - l;

        int r = (int) Math.floor(Math.random() * (diff + 1)); // '+1' because Math.random() returns 0..0.99, it does not include 'diff' value, so we do +1, so 'diff + 1' won't be included, but just 'diff' value will be.
  
        return l + r;//add the random number that was selected within distance between low and up to the lower limit.      
}
Crandall answered 22/9, 2022 at 12:57 Comment(0)
A
0

Typescript solution with digits:

function getRandomNumber( min:number, max:number, digits=0 ):number {
    // 0=1, 2=10, 3=100, 4=1000, ...
    const multiplier = digits >= 1 ? Math.pow( 10, digits ) : 1 
    const start = min * multiplier
    const space = (max-min) * multiplier
    const int = Math.floor( start + Math.random()*(space+1) ) 
    return int / multiplier
}

Advanced solution with

  • a, b(number) — flexible min max parameter
  • digits(boolean) — define count of digits
  • includeAB(boolean) — define if you want to exclude a and b from results
function getRandomNumberAdv( a:number, b:number, digits=0, includeAB=true ):number {
    const multiplier = digits >= 1 ? Math.pow( 10, digits ) : 1 
    const border = includeAB ? 0 : 1 
    const start = Math.min(a,b) * multiplier + border
    const space = Math.max(a,b) * multiplier - start - border
    const int = Math.floor( start + Math.random()*(space+1) ) 
    return int / multiplier
}

Test of getRandomNumberAdv( 1, -1, 1, false ):


  const statistic:any = {}
  for (let i = 0; i < 1000000; i++) {
      const v = getRandomNumberAdv( 1, -1, 1, false )
      if( statistic[v] === undefined ) statistic[v]=0
      statistic[v]++
  }
  console.log( JSON.stringify( statistic, null, 2 ))

Results of getRandomNumberAdv( 1, -1, 1, false ):

{
    "-0.9": 52638,
    "-0.8": 52862,
    "-0.7": 52658,
    "-0.6": 52217,
    "-0.5": 52634,
    "-0.4": 52894,
    "-0.2": 52420,
    "-0.3": 52838,
    "-0.1": 52599,
     "0"  : 52604,
     "0.1": 52615,
     "0.2": 52286,
     "0.3": 52129,
     "0.4": 52495,
     "0.5": 52920,
     "0.6": 52707,
     "0.7": 52855,
     "0.8": 52827,
     "0.9": 52802,
  }

Playground Link

Amphibology answered 15/12, 2023 at 13:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.