Forum Bugs

The Javascript random number generator is not being seeded

StoneCypher
The Javascript random number generator is not being seeded.

John Haugeland is http://fullof.bs/

mikeday
You don't like your random numbers to be deterministic? :D
StoneCypher
Here is the relatively horrible workaround I'm using for now.

This is the L'Ecuyer generator. It generates floats with a period of 1/233280, meaning it's reasonably distributed for ints of 2^16 or smaller.

You can use this for 16-bit int values, signed or unsigned. Do *not* use this for fine valued floats, and do *not* expect good distribution out of this. This is a garbage generator, and it's using multiple string transitions

Because of the severe limitations of the ECMA float type, this probably also has severe drift issues. I chi squared it out to ten million rolls; it was fine. That's good enough for what I'm currently doing.

It's hard to imagine a less cryptographically secure generator than this hot mess I'm about to paste. :D

Still, if you're just doing simple stuff, if good distribution isn't very important, and if most discussion of a "good generator" is over your head, this might fit the bill.

This script attaches itself to the ECMA math object and replaces the random number generator with a dramatically inferior generator. The reason we bother at all is that unlike the standard ECMA generator, this generator can be seeded. This is desirable for two reasons: 1) the PrinceXML generator isn't being seeded right now, so this lets us temporarily step beyond that with the clock, and 2) maybe you want repeatable sequences.

This generator self-seeds from the clock.

// see "Efficient and Portable Combined Random Number Generators",
// Pierre L'Ecuyer, Communications of the ACM, June, 1988 (v31 #6)


function rSeedable(seed) {





    // god this is horrible
    // abs because of 31-bit overflow problems; only matters over the domain 0..233279, so screw it

    var PrinceSafeTrunc = function(X) {

      var S = X.toString();
      var P = S.indexOf('.');

      return Math.abs((P == -1)? X : parseInt(S.substring(0, P), 10));

    }





    var rSeed = (seed === undefined)? PrinceSafeTrunc(new Date().getTime()) : seed;





    this.seed = function(X) {
      rSeed = X;
    }





    this.genFloat = function() {

      rSeed = PrinceSafeTrunc(((rSeed * 9301) + 49297) % 233280);

      return rSeed / (233280.0);

    }

}





var rng = new rSeedable();

Math.randomizer = rng;
Math.random     = rng.genFloat;


Too long, didn't read?

Put this script in your <head> and Math.random() will start working afterwards.

Stop using this immediately after the PrinceXML one is fixed, because the real thing is far superior to this atrocity.

John Haugeland is http://fullof.bs/

mikeday
In Prince 8.1 we have added a Math.seedRandom() function that can be used to seed the random number generator, eg. with the current time.