{"id":4199,"date":"2010-10-09T06:40:57","date_gmt":"2010-10-09T04:40:57","guid":{"rendered":"http:\/\/blog.ginchen.de\/?p=4199"},"modified":"2010-10-10T12:46:58","modified_gmt":"2010-10-10T10:46:58","slug":"javascripts-math-random-wenn-zufall-keiner-ist","status":"publish","type":"post","link":"http:\/\/blog.ginchen.de\/en\/2010\/10\/09\/javascripts-math-random-wenn-zufall-keiner-ist\/","title":{"rendered":"Javascript&#8217;s Math.random() &#8211; when random isn&#8217;t random"},"content":{"rendered":"<p>Yesterday I wrote a function in Javascript that should return random integers in a given range; basically just the same as the PHP function <code>rand($min, $max)<\/code>. 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 <code>Math.round()<\/code> was the culprit.<\/p>\r\n\r\n\r\n<!--more-->\r\n\r\n\r\n\r\n\r\n<h3>Math.round() &#8211; not such a round thing<\/h3>\r\n\r\n<p>Suppose you want to generate a random number bewtween <code>1<\/code> and <code>10<\/code>. That might look like this:<\/p>\r\n\r\n<pre lang=\"javascript\">\r\nrandomNumber = Math.round(Math.random() * 9) + 1;\r\n<\/pre>\r\n\r\n<p>The expected result would be that all numbers will occur with a probability of <code>1\/10<\/code> (or <code>10%<\/code>). Unfortunately, they don&#8217;t. Instead, <code>1<\/code> and <code>10<\/code> appear less often than the remaining numbers. Why is that so?<br \/>\r\nQuite simple: The result of <code>Math.random()*9<\/code> can take any value between <code>0<\/code> and <code>8,<span style=\"text-decoration: overline\">9<\/span><\/code>. And now let&#8217;s have a look at how the values are rounded afterwards:<\/p>\r\n\r\n<table style=\"font: 11px 'Courier New', Courier, Fixed, sans-serif; width: 100%; text-align: center;\">\r\n<tr>\r\n<td width=\"5%\">0 &#8211; 0,49<\/td>\r\n<td>0,5 &#8211; 1,49<\/td>\r\n<td>1,5 &#8211; 2,49<\/td>\r\n<td>2,5 &#8211; 3,49<\/td>\r\n<td>3,5 &#8211; 4,49<\/td>\r\n<td>4,5 &#8211; 5,49<\/td>\r\n<td>5,5 &#8211; 6,49<\/td>\r\n<td>6,5 &#8211; 7,49<\/td>\r\n<td>7,5 &#8211; 8,49<\/td>\r\n<td width=\"5%\">8,5 &#8211; 8,99<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>0<\/td>\r\n<td>1<\/td>\r\n<td>2<\/td>\r\n<td>3<\/td>\r\n<td>4<\/td>\r\n<td>5<\/td>\r\n<td>6<\/td>\r\n<td>7<\/td>\r\n<td>8<\/td>\r\n<td>9<\/td>\r\n<\/tr>\r\n<\/table>\r\n\r\n<p>As you can see in this table (I tried to make it visually clearer using different column widths), there&#8217;s only an interval of <code>0.5<\/code> each that has the chance of becoming rounded to <code>0<\/code> or <code>9<\/code>, while for all the other numbers it&#8217;s an interval of <code>1<\/code>. 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?<\/p>\r\n\r\n<h3>Math.floor() is your friend! :)<\/h3>\r\n\r\n<p>Exactly, let&#8217;s just always round the number down. But wait! What about the <code>10<\/code>? It will no longer show up then, because the maximum possible value of <code>Math.random()*9<\/code> will always be rounded down to <code>8<\/code>! True &#8211; so we&#8217;ll simply increase the multiplier by <code>1<\/code>:<\/p>\r\n\r\n<pre lang=\"javascript\">\r\nrandomNumber = Math.floor(Math.random() * 10) + 1;\r\n<\/pre>\r\n\r\n<p>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:<\/p>\r\n\r\n<pre lang=\"javascript\">\r\nfunction rand(min, max) {\r\n\treturn Math.floor(Math.random() * (max - min + 1)) + min;\r\n}\r\n<\/pre>\r\n\r\n<h3>P.S.: There is no seed parameter!<\/h3>\r\n\r\n<p>There is a persistent rumor that one could pass a value (a so-called &#8220;seed&#8221; parameter) to the <code>random()<\/code> 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 &#8220;random&#8221;:<\/p>\r\n\r\n<pre lang=\"javascript\">\r\nnow = new Date();\r\nseed = now.getMilliseconds();\r\nrandomNumber = Math.floor(Math.random(seed) * 10) + 1\r\n<\/pre>\r\n\r\n<p>Well &#8230; Unfortunately, this is nonsense. :) Such a parameter does not exist. You won&#8217;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 <code>Math.random()<\/code> always uses the current time as its calculation basis anyway.)<\/p>","protected":false},"excerpt":{"rendered":"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 [&hellip;]","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[76],"tags":[154,474,472,473,471],"_links":{"self":[{"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/posts\/4199"}],"collection":[{"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/comments?post=4199"}],"version-history":[{"count":65,"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/posts\/4199\/revisions"}],"predecessor-version":[{"id":4266,"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/posts\/4199\/revisions\/4266"}],"wp:attachment":[{"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/media?parent=4199"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/categories?post=4199"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.ginchen.de\/en\/wp-json\/wp\/v2\/tags?post=4199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}