JavaScript

Chelsea Crisp
Chelsea Crisp
4,824 Points

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

Can someone just explain the logic behind this math/function? What does the asterisk signify? Why the + 1?

The asterisk means multiplication.

Chelsea Crisp
Chelsea Crisp
4,824 Points

I understand the asterisk means multiply but what is being multiplied?

The return value of Math.random() is being multiplied with the result of (max - min + 1)

Let us know if Chris's update clears it up for you.

5 Answers

Hi Chelsea,

Maybe it will help to see how the formula can be derived starting only with Math.random() and Math.floor(). That way you'll know that it's correct and more importantly why it's correct.

I'll try to provide a conceptual understanding of what's going on with the formula.

We know that Math.random() returns a value in the range [0, 1). 0 is included but 1 is excluded. You can think of it as the range 0 to 0.999999...

Now let's pass that result to the Math.floor() function.

Math.floor(Math.random());

Since floor will truncate the decimal and give you back the whole number part we're always going to get 0 here. Make sure you understand that or the rest isn't going to make any sense. Ask questions if you need to.

We can only get 1 integer out of this. It's not so much important that the integer is 0 but that we can only get 1 integer out.

If we are going to be able to get more numbers out of this then we need to make that range bigger. When you multiply something by 2 it becomes twice as big as it was before. It scales up by a factor of 2. Let's see what happens when we multiply Math.random() by 2

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

That will give us a new range of 0 to 1.999999... which is twice as big as the range we started with.

What happens when those numbers are passed into Math.floor? All the numbers generated from 0 to 0.9999... will be truncated to 0 and all the numbers from 1 to 1.9999... will be truncated to 1

Now we're able to get 2 different integers out of this. If we multiply by 2 we can get 2 numbers back. It stands to reason that if we multiply by 6 then we will be able to get 6 numbers out.

That will give us a range that's 6 times as big, 0 to 5.99999.....

I won't write it all out but after passing through the floor function you would get

0 to .99999... -> 0
1 to 1.99999... -> 1
...
5 to 5.99999... -> 5

In general, whatever you multiply Math.random() by is how many integers you'll be able to generate.

Now we can start deriving the formula and I'll use a specific example to help.

Let's say we want to generate numbers from 5 to 10 inclusive. We need to know how many numbers are there.

Setting up the variables -

var max = 10;
var min = 5;

If we list them out, 5, 6, 7, 8, 9, 10 and count them we see that there are 6 total numbers. We know from before that we're going to have to multiply by 6 in order to get 6 numbers out.

How can we come up with the 6 using our max and min variables?? If I do max - min I get 5 which is 1 short. max - min gives you the distance from 5 to 10. You always have to add 1 to that if you want the total amount of numbers.

That gives us the expression max - min + 1

Putting that into the formula,

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

It's important that max - min + 1 is enclosed in parentheses so that all of that happens before the multiplication.

At this point the formula can generate the correct amount of numbers but they always start at 0 because the range from Math.random starts from 0.

0, 1, 2, 3, 4,  5 // What we have
5, 6, 7, 8, 9, 10 // What we want

Notice that if we add 5 to all the numbers in the first row, we'll get the second row. 5 is what our min value is in the example.

So if we add the min value onto the end of our formula, it will shift all the numbers over to the ones we want.

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

You can think of it as a 2 step operation, you scale up the range, and then you shift it.

I meant for this to be shorter but I hope it helps you out.

Chelsea Crisp
Chelsea Crisp
4,824 Points

This was the perfect explanation. I totally get it now, thank you so much!

Gerard Dlima
Gerard Dlima
11,908 Points

Great Explanation.Thanks!

Niklas Albinsson
Niklas Albinsson
6,045 Points

Thank you for this answer, perfectly explained.

Perfect explanation.

Andrew Denson
Andrew Denson
4,544 Points

I just posted a question about this. Guess i should have looked for the answer first. Glad I found it though.
Thanks for answer Jason. Big help.

jennyellis
jennyellis
8,464 Points

Your explanation was awesome. Thank you so much for taking the time to describe this so well!

Chris Davis
Chris Davis
16,277 Points

Math.random() generates a random floating point number (decimal) from 0 up to but not including 1 - Example - .25

var myRand = Math.random();
console.log(myRand);

When you combine Math.random() * 10 you are saying, give me a random floating point number from 0 up to but not including 10 - Example - 4.25

var myRand = Math.random() * 10;
console.log(myRand);

When you combine Math.floor(Math.random() * 10) you are asking for a random floating point number from 0 up to but not including 10 then Math.floor() will round down to a whole number - Example - 4

var myRand = Math.floor(Math.random() * 10);
console.log(myRand);

When you combine Math.floor(Math.random() * 10) + 1 you are saying give me a random whole number from 0 up to but not including 10, then the +1 ensures that you receive a random number from 1 - 10

var myRand = Math.floor(Math.random() * 10) + 1;
console.log(myRand);

Max and min is your range, say you want to generate a random whole number from 2 (min) to 10 (max). Let me see if i can explain this! Math.floor(Math.random() * (max - min + 1)) is generating a whole number between the range of 0 to 8. The (max - min + 1) is the logic that creates the range. When you add the + min at the end you are adding the +2 to your range and end up with a random number from 2 to 10. It took me a little while to wrap my head around this logic concept, however it becomes easier to understand the more you use it.

var myRand = Math.floor(Math.random () * (max - min + 1) + min);
console.log(myRand);

I hope this helps a little bit. Here is an example I have updated the fiddle to include the final logic

changed from comment to answer

Chelsea Crisp
Chelsea Crisp
4,824 Points

Thanks! That was very helpful. Although I still don't understand the "max - min" before the + 1 or the "+ min" at the end.

This was a formula given to me during an random number generator exercise by treehouse.

Chelsea Crisp
Chelsea Crisp
4,824 Points

"Math.floor(Math.random() * (max - min + 1)) is generating a whole number between the range of 0 to 8."

How are you getting 8? 10 - 2 + 1 = 9? Are you adding 2 to 9 and 0 to get a range between 2-10? The math adds up to 11 but that way 10 would be included because it's up to but not including 11?

Also, why can't you just say something like Math.floor(Math.random() * (max - 1) + min)?

Chris Davis
Chris Davis
16,277 Points

I have updated my explanation to hopefully help you understand generating a random whole number within a range :)

Adam Maley
Adam Maley
5,854 Points

This is confusing...

var myRand = Math.floor(Math.random () * (max - min + 1) + min); If I insert Math.random= 0.5 as the number generated. Max=10 Min=1 Is this the correct thinking?

var myRand = Math.floor(0.5 * (10 - 1 + 1) + min);
var myRand = Math.floor(0.5 * (9 + 1) + min);
var myRand = Math.floor(0.5 * (10) + min);
var myRand = Math.floor(5 + min);
var myRand = Math.floor(6);    <-------- In my case because of the 0.5 it happened to be already at an Integer of 6?
var myRand = 6

Hi Adam,

Yes, that's correct. If Math.random() generated 0.5 in this scenario then you would get a 6.

All the numbers that Math.random() generates from 0.5 to 0.59999... would result in a final value of 6