Oct

2010

## Javascript’s Math.random() – when random isn’t random

Yesterday I wrote a function in Javascript that should return random integers in a given range; basically just the same as the PHP function `rand($min, $max)`

. But after a few test runs I noticed that the numbers were not quite as random as they should be; some of them appeared more often than expected, others less. It turned out that rounding with `Math.round()`

was the culprit.

### Math.round() – not such a round thing

Suppose you want to generate a random number bewtween `1`

and `10`

. That might look like this:

randomNumber = Math.round(Math.random() * 9) + 1; |

The expected result would be that all numbers will occur with a probability of `1/10`

(or `10%`

). Unfortunately, they don’t. Instead, `1`

and `10`

appear less often than the remaining numbers. Why is that so?

Quite simple: The result of `Math.random()*9`

can take any value between `0`

and `8,9`

. And now let’s have a look at how the values are rounded afterwards:

0 – 0,49 | 0,5 – 1,49 | 1,5 – 2,49 | 2,5 – 3,49 | 3,5 – 4,49 | 4,5 – 5,49 | 5,5 – 6,49 | 6,5 – 7,49 | 7,5 – 8,49 | 8,5 – 8,99 |

0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

As you can see in this table (I tried to make it visually clearer using different column widths), there’s only an interval of `0.5`

each that has the chance of becoming rounded to `0`

or `9`

, while for all the other numbers it’s an interval of `1`

. This explains why the desired minimum and maximum values occur only half as often as the remaining numbers. But how else can we get rid of the decimal places?

### Math.floor() is your friend! :)

Exactly, let’s just always round the number down. But wait! What about the `10`

? It will no longer show up then, because the maximum possible value of `Math.random()*9`

will always be rounded down to `8`

! True – so we’ll simply increase the multiplier by `1`

:

randomNumber = Math.floor(Math.random() * 10) + 1; |

Now the random numbers are distributed as expected, that is about evenly. With this knowledge you can now finally write a properly functioning, easy to use, PHP-like random function:

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

### P.S.: There is no seed parameter!

There is a persistent rumor that one could pass a value (a so-called “seed” parameter) to the `random()`

function, which it should then use as the basis for its random calculation. Thus, it has become a bad habit to pass the current seconds or milliseconds to the function in the hope that the numbers will somehow become more “random”:

now = new Date(); seed = now.getMilliseconds(); randomNumber = Math.floor(Math.random(seed) * 10) + 1 |

Well … Unfortunately, this is nonsense. :) Such a parameter does not exist. You won’t find it in any Javascript documentation either. Any value that you pass to the function is simply being ignored. (However, the construction with the time is kind of extra foolish, because `Math.random()`

always uses the current time as its calculation basis anyway.)

6:17 am

## Himanshu Monga

Thanks for the information was really help ful and added value..

Thanks a ton!