Make JavaScript Math.random() useful

Make JavaScript Math.random() useful

By Andrew Penry

Posted on 08.04.04

The JavaScript function Math.random() randomly generates a number from 0 to slightly less than 1 (shown as <1). This is great, and all, but when was the last time someone told you to pick a number between 0 and slightly less than 1? Never? How do we transform these numbers into something useable, say a whole number between 1 and 3. (One and ten are more common, but the illustrations would be too huge.) First, we could multiply. Let’s try multiplying by 3.
Math.random() * 3
This gets us numbers from 0 to <3. But we want between 1 and 3. We’ll try multiplying and adding.
Math.random() * 2 + 1
Great. This will get us numbers from 1 to <3. (First it generates a number from 0 to <2, then adds 1.) Lets see how this looks on a number line:
1 1.5 2 2.5 3 |-----|-----|-----|-----|
Good. But this still gives us decimal numbers such as 1.56734. We want whole number. So naturally we should round. Lets try:
Math.round(Math.random*2+1)
This will produce whole numbers between 1 and 3 inclusive. However, the numbers are perfectly random. To be perfectly random each number should appear the same number of times, but in this case the number 2 will appear most often. Let’s put this on a number line. Recall from elementary school that things <.5 round down and >.5 round up.
1 1.5 2 2.5 3 |-----|-----|-----|-----| 1<<<<< >>>>>2<<<<< >>>>>3
So as you can see, the segment that rounds to two is twice as long as the segments that round to one or three.

The fix

How about we change our math a little and always round up. The function we need is called the ceiling function because it rounds a number up to the “ceiling.”
Math.ceil(Math.random()*3)
Going to the number line:
0 .5 1 1.5 2 2.5 3 |-----|-----|-----|-----|-----|-----| 0>>>>>>>>>>>1>>>>>>>>>>>2>>>>>>>>>>>3
Awesome. However, (oh no, not again) remember how the Math.random() function gives us numbers from 0 to <1? That mean there is a super-slim chance of getting exactly 0. Math.ceil(0) equals 0. So there is a slim chance we will get 0 as a result.

The real fix

We don’t have to round to get integers. We can truncate. This means that we just throw away anything after the decimal point. OK, so this is technically the same as always rounding down, but whatever. This function is called the floor function.
Math.floor(Math.random()*3+1)
Lets go through it. First we get a number between 0 and <3 and then add 1 to it. This gives us 1 to <4. Remember that slightly less than 4 could be 3.99999 but it will never be 4. So when we floor the number we will always get a whole number between 1 and 3 inclusive. Check out the number line:
1 1.5 2 2.5 3 3.5 4 |-----|-----|-----|-----|-----|-----| 1<<<<<<<<<<<2<<<<<<<<<<<3<<<<<<<<<<<
In conclusion, random numbers are only purely random if you transform them correctly. Otherwise you get skewed and unexpected results. Use:
Math.floor(Math.random()*max+1)
to get numbers between 1 and max. Homework: make a function to get numbers between min and max. Play around with these functions at: ThePenry.net Math.random() page. Knowledge is power. Power corrupts. You are now more corrupted.
Copyright © 2004-2008 by Andrew Penry.
sitemap RGB Color Columbus Photography Free Word Search Maker monty hall game Hangman John Dewey