loading...
Cover image for Understanding Math.random() in JavaScript!

Understanding Math.random() in JavaScript!

vunderkind profile image mogwai ・3 min read

It’s incredible the number of times you’ll have to use Math.random() (out of all the Math methods that ship out-of-the-box with JavaScript).

If you’re a creative coder, you’ll need it to make generative art (even though many of the tools of creative coding ship their own flavor of the trusty Math.random()). As a result, it’s probably a great idea to reason about how Math.random() works.

At its very base, Math.random() is designed to do only one thing: generate a number between 0 and 1. I like to think of it as a white noise machine, generating white and black pixels to fill a whole screen. That analogy is powerful when you consider that white noise machines go into the creation of mosaics and even procedurally generated clouds, among other things.

In other words, Math.random() is deceptively simple:

0≤ n <1
//What Math.random generates

Math.random() generates a number between zero and one, but never (or rarely ever) generates one itself.

Extending Math.random()

If we think of 0≤n<1 as an algorithm for the procedural generation of random floating digits, we can then generate numbers not limited to 0 and one. We only need to reduce the skeleton of our desired range to the base format.

Say you want to generate a number between 5 and 15. This is the mental sequence you’ll follow:

  • I need a number between 5 and 15.
  • This can be represented mathematically as 5≤n<16 (can you guess why we write 16 and not 15?)
  • But Math.random() can only think in 1s and 0s. So how to get things in agreement?
  • First subtract five from every part of that mathematical model of computation.
  • That gives us 5–5≤n-5<16–5
  • …which is 0≤n-5<11
  • Okay. So we have a zero on one end. But we need a 1, not an 11, on the other end!
  • Oh, I know! Let’s divide everything by 11!
  • 0/11≤(n-5)/11<11/11
  • That’s 0≤(n-5)/11<1
  • Yay!
  • But we aren’t done :(
  • You see, (n-5)/11 is r. That is, the random number Math.random() will generate. What we want to get it the factor we’ll multiply r by to get numbers within the range we want (in this case, 5–15). To do this, we have to find n.
  • r = (n-5)/11
  • Multiply both sides by 11
  • n-5 = r*11
  • Add five to both sides
  • n = (r*11) + 5 Let’s take this for a spin, shall we? Let’s write a function called fiveToFifteen. Carbon

And it works!

But what if you wanted to change the number from five and fifteen to, say 8 and 19? Will you have to do that 18-step reasoning we did earlier?

Mercifully not. Instead of thinking in pure numbers (5 and 15), we can think in terms of min and max.

0 is min, 1 is max.

So we can start with this basic idea instead:
min ≤n<max
If we go through the 18 steps again, we have something like this at step 9:

  • min-min≤n-min<max-min, which gives us 0≤n-min<max-min
  • Divide through by (max-min), and we get:
  • 0/(max-min)≤n-min/(max-min)<(max-min)/(max-min)
  • 0≤n-min/(max-min)<1

Aha.

We can then run r = (n-min)/max-min

  • Multiply both sides by (max-min), and we get r * (max-min) = n-min
  • Add min r * (max-min) + min = n

We can then rewrite our function to adapt to any random number generation need like this:

function anyRandomNumber(min, max){
    let r = Math.random();
    r*=(max-min);
    r+=min;
    console.log(Math.floor(r))
}

anyRandomNumber(69,87)

Thanks to Scrimba’s math for frontend developers for helping me understand this, and I hope it is a useful mental model for you as well!
This was originally published on my blog

Posted on by:

vunderkind profile

mogwai

@vunderkind

JavaScript enthusiast interested in making screens more interesting - and ultimately, data easier/less painful to parse.

Discussion

markdown guide
 

Hey, Great article!!
Just a little suggestion tho'
You could add the name of the language to the markdown tag to help format the code. something like


 

How do you mean? I can't see anything in the block of code you're sharing.

 

In your article, you added a code block, although it wasn't formatted by dev.to! if you want to make it highlighted with colors and all that good stuff, you should add the name of the programming language right after the three opening backticks used for writing a code block, I tried to demonstrate it in my earlier comment but it was converted to markdown, you could check out this post about it dev.to/hoverbaum/how-to-add-code-h...

Ah, seen. And thanks - just implemented it. It's perfect.