Repeatable random numbers in JavaScript

Ever since programming BASIC on the Spectrum I’d wondered why it was possible to seed a “random” number generator. But then I found I wanted to do something that would produce repeatable results, but look like a random sequence. Strangely, although JavaScript alongs you to specify a seed for Math.random() the numbers that follow aren’t a repeated sequence. I’m guessing the system clock comes into it.

So after some Googling for an equation to generate numbers I put together the following function. It works on a sequence of 2^32 numbers, in “random” order. (I believed the equation I found – I didn’t test the completeness of it, but it looks pretty random to me.) So, just call Random.next() to get a decimal between 0 and 1, or pass in a range (lower,upper) and you get a random number between the two.

var Random =
{
 seed : 12345,
 //Returns a random number between 0 and 1
 next : function(lower,upper)
 {
  var maxi = Math.pow(2,32);
  this.seed = (134775813 * (this.seed + 1))
     % maxi;
  var num = (this.seed) / maxi;
  if(typeof lower!='undefined')
  {
   var range = upper - lower;
   num *= range;
   num += lower;
  }
  return num;
 }
}

Set “Random.seed” to taste.

One thought on “Repeatable random numbers in JavaScript”

  1. Your RNG comes from 64-bit C, and JavaScript cannot handle that many significant digits, and it will begin repeating in a tight loop very rapidly. JS only handles 2^53 bits (for significant digits), so you have to scale down the numbers. Google LCG and find a Wikipedia article that describes the LCG.Here's an LCG that works very well in JS.// global variablesvar d3; // number < dmod3var dmod3=1073741789; // prime, near power of 2var dmul3=885713; // primefunction Rand3 (seed) {var t; if (arguments.length > 0) d3=seed; t = d3 * dmul3 + 1; d3 = t % dmod3; return d3 / dmod3;}where seed < dmod3ron853211&yahoo.com;http://rascalcode.home.bresnan.net/rascal.html

Leave a Reply to Anonymous Cancel reply

Your email address will not be published. Required fields are marked *