Editing Pseudo Random Number Generators This edit will create a new revision. Your details (optional) Name Email (won’t be displayed; might be used for Gravatar) URL Test case details Title * Published (uncheck if you want to fiddle around before making the page public) Description (in case you feel further explanation is needed)(Markdown syntax is allowed) Tests different PRNGs in JavaScript taken from this page: http://baagoe.org/en/wiki/Better_random_numbers_for_javascript Added another PRNG from http://freespace.virgin.net/hugo.elias/models/m_perlin.htm Are you a spammer? (just answer the question) Preparation code Preparation code HTML (this will be inserted in the <body> of a valid HTML5 document in standards mode) (useful when testing DOM operations or including libraries) <script> // Mash: http://baagoe.org/en/wiki/Mash function Mash() { var n = 0xefc8249d; var mash = function(data) { data = data.toString(); for (var i = 0; i < data.length; i++) { n += data.charCodeAt(i); var h = 0.02519603282416938 * n; n = h >>> 0; h -= n; h *= n; n = h >>> 0; h -= n; n += h * 0x100000000; // 2^32 } return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 }; mash.version = 'Mash 0.9'; return mash; } // MRG32k3a: http://baagoe.org/en/wiki/MRG32k3a function MRG32k3a() { return (function(args) { // Copyright (c) 1998, 2002 Pierre L'Ecuyer, DIRO, Université de Montréal. // http://www.iro.umontreal.ca/~lecuyer/ var m1 = 4294967087; var m2 = 4294944443; var s10 = 12345, s11 = 12345, s12 = 123, s20 = 12345, s21 = 12345, s22 = 123; if (args.length === 0) { args = [+new Date()]; } var mash = Mash(); for (var i = 0; i < args.length; i++) { s10 += mash(args[i]) * 0x100000000; // 2 ^ 32 s11 += mash(args[i]) * 0x100000000; s12 += mash(args[i]) * 0x100000000; s20 += mash(args[i]) * 0x100000000; s21 += mash(args[i]) * 0x100000000; s22 += mash(args[i]) * 0x100000000; } s10 %= m1; s11 %= m1; s12 %= m1; s20 %= m2; s21 %= m2; s22 %= m2; mash = null; var uint32 = function() { var m1 = 4294967087; var m2 = 4294944443; var a12 = 1403580; var a13n = 810728; var a21 = 527612; var a23n = 1370589; var k, p1, p2; /* Component 1 */ p1 = a12 * s11 - a13n * s10; k = p1 / m1 | 0; p1 -= k * m1; if (p1 < 0) p1 += m1; s10 = s11; s11 = s12; s12 = p1; /* Component 2 */ p2 = a21 * s22 - a23n * s20; k = p2 / m2 | 0; p2 -= k * m2; if (p2 < 0) p2 += m2; s20 = s21; s21 = s22; s22 = p2; /* Combination */ if (p1 <= p2) return p1 - p2 + m1; else return p1 - p2; }; var random = function() { return uint32() * 2.3283064365386963e-10; // 2^-32 }; random.uint32 = uint32; random.fract53 = function() { return random() + (uint32() & 0x1fffff) * 1.1102230246251565e-16; // 2^-53 }; random.version = 'MRG32k3a 0.9'; random.args = args; return random; } (Array.prototype.slice.call(arguments))); }; // Xorshift03: http://baagoe.org/en/wiki/Xorshift03 function Xorshift03() { return (function(args) { // George Marsaglia, 13 May 2003 // http://groups.google.com/group/comp.lang.c/msg/e3c4ea1169e463ae var x = 123456789, y = 362436069, z = 521288629, w = 88675123, v = 886756453; if (args.length == 0) { args = [+new Date]; } var mash = Mash(); for (var i = 0; i < args.length; i++) { x ^= mash(args[i]) * 0x100000000; // 2^32 y ^= mash(args[i]) * 0x100000000; z ^= mash(args[i]) * 0x100000000; v ^= mash(args[i]) * 0x100000000; w ^= mash(args[i]) * 0x100000000; } mash = null; var uint32 = function() { var t = (x ^ (x >>> 7)) >>> 0; x = y; y = z; z = w; w = v; v = (v ^ (v << 6)) ^ (t ^ (t << 13)) >>> 0; return ((y + y + 1) * v) >>> 0; } var random = function() { return uint32() * 2.3283064365386963e-10; // 2^-32 }; random.uint32 = uint32; random.fract53 = function() { return random() + (uint32() & 0x1fffff) * 1.1102230246251565e-16; // 2^-53 }; random.version = 'Xorshift03 0.9'; random.args = args; return random; } (Array.prototype.slice.call(arguments))); }; // KISS07: http://baagoe.org/en/wiki/KISS07 function KISS07() { return (function(args) { // George Marsaglia, 2007-06-23 //http://groups.google.com/group/comp.lang.fortran/msg/6edb8ad6ec5421a5 var x = 123456789; var y = 362436069; var z = 21288629; var w = 14921776; var c = 0; if (args.length == 0) { args = [+new Date]; } var mash = Mash(); for (var i = 0; i < args.length; i++) { x ^= mash(args[i]) * 0x100000000; // 2^32 y ^= mash(args[i]) * 0x100000000; z ^= mash(args[i]) * 0x100000000; w ^= mash(args[i]) * 0x100000000; } if (y === 0) { y = 1; } c ^= z >>> 31; z &= 0x7fffffff; if ((z % 7559) === 0) { z++; } w &= 0x7fffffff; if ((w % 7559) === 0) { w++; } mash = null; var uint32 = function() { var t; x += 545925293; x >>>= 0; y ^= y << 13; y ^= y >>> 17; y ^= y << 5; t = z + w + c; z = w; c = t >>> 31; w = t & 0x7fffffff; return x + y + w >>> 0; }; var random = function() { return uint32() * 2.3283064365386963e-10; // 2^-32 }; random.uint32 = uint32; random.fract53 = function() { return random() + (uint32() & 0x1fffff) * 1.1102230246251565e-16; // 2^-53 }; random.args = args; random.version = 'KISS07 0.9'; return random; } (Array.prototype.slice.call(arguments))); }; // LFib: http://baagoe.org/en/wiki/LFib function LFib() { return (function(args) { var k0 = 255, k1 = 52, k2 = 0; var s = []; var mash = Mash(); if (args.length === 0) { args = [+new Date()]; } for (var j = 0; j < 256; j++) { s[j] = mash(' '); s[j] -= mash(' ') * 4.76837158203125e-7; // 2^-21 if (s[j] < 0) { s[j] += 1; } } for (var i = 0; i < args.length; i++) { for (var j = 0; j < 256; j++) { s[j] -= mash(args[i]); s[j] -= mash(args[i]) * 4.76837158203125e-7; // 2^-21 if (s[j] < 0) { s[j] += 1; } } } mash = null; var random = function() { k0 = (k0 + 1) & 255; k1 = (k1 + 1) & 255; k2 = (k2 + 1) & 255; var x = s[k0] - s[k1]; if (x < 0.0) { x += 1.0; } x -= s[k2]; if (x < 0.0) { x += 1.0; } return s[k0] = x; } random.uint32 = function() { return random() * 0x100000000 >>> 0; // 2^32 }; random.fract53 = random; random.version = 'LFib 0.9'; random.args = args; return random; } (Array.prototype.slice.call(arguments))); } // LFIB4: http://baagoe.org/en/wiki/LFIB4 function LFIB4() { return(function(args) { // George Marsaglia's LFIB4, //http://groups.google.com/group/sci.crypt/msg/eb4ddde782b17051 var k0 = 0, k1 = 58, k2 = 119, k3 = 178; var s = []; var mash = Mash(); if (args.length === 0) { args = [+new Date()]; } for (var j = 0; j < 256; j++) { s[j] = mash(' '); s[j] -= mash(' ') * 4.76837158203125e-7; // 2^-21 if (s[j] < 0) { s[j] += 1; } } for (var i = 0; i < args.length; i++) { for (var j = 0; j < 256; j++) { s[j] -= mash(args[i]); s[j] -= mash(args[i]) * 4.76837158203125e-7; // 2^-21 if (s[j] < 0) { s[j] += 1; } } } mash = null; var random = function() { var x; k0 = (k0 + 1) & 255; k1 = (k1 + 1) & 255; k2 = (k2 + 1) & 255; k3 = (k3 + 1) & 255; x = s[k0] - s[k1]; if (x < 0) { x += 1; } x -= s[k2]; if (x < 0) { x += 1; } x -= s[k3]; if (x < 0) { x += 1; } return s[k0] = x; } random.uint32 = function() { return random() * 0x100000000 >>> 0; // 2^32 }; random.fract53 = random; random.version = 'LFIB4 0.9'; random.args = args; return random; } (Array.prototype.slice.call(arguments))); } // Alea: http://baagoe.org/en/wiki/Alea function Alea() { return (function(args) { var s0 = 0; var s1 = 0; var s2 = 0; var c = 1; if (args.length == 0) { args = [+new Date]; } var mash = Mash(); s0 = mash(' '); s1 = mash(' '); s2 = mash(' '); for (var i = 0; i < args.length; i++) { s0 -= mash(args[i]); if (s0 < 0) { s0 += 1; } s1 -= mash(args[i]); if (s1 < 0) { s1 += 1; } s2 -= mash(args[i]); if (s2 < 0) { s2 += 1; } } mash = null; var random = function() { var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32 s0 = s1; s1 = s2; return s2 = t - (c = t | 0); }; random.uint32 = function() { return random() * 0x100000000; // 2^32 }; random.fract53 = function() { return random() + (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 }; random.version = 'Alea 0.9'; random.args = args; return random; } (Array.prototype.slice.call(arguments))); }; // Kybos: http://baagoe.org/en/wiki/Kybos function Kybos() { return (function(args) { var s0 = 0; var s1 = 0; var s2 = 0; var c = 1; var s = []; var k = 0; var mash = Mash(); var s0 = mash(' '); var s1 = mash(' '); var s2 = mash(' '); for (var j = 0; j < 8; j++) { s[j] = mash(' '); } if (args.length == 0) { args = [+new Date]; } for (var i = 0; i < args.length; i++) { s0 -= mash(args[i]); if (s0 < 0) { s0 += 1; } s1 -= mash(args[i]); if (s1 < 0) { s1 += 1; } s2 -= mash(args[i]); if (s2 < 0) { s2 += 1; } for (var j = 0; j < 8; j++) { s[j] -= mash(args[i]); if (s[j] < 0) { s[j] += 1; } } } var random = function() { var a = 2091639; k = s[k] * 8 | 0; var r = s[k]; var t = a * s0 + c * 2.3283064365386963e-10; // 2^-32 s0 = s1; s1 = s2; s2 = t - (c = t | 0); s[k] -= s2; if (s[k] < 0) { s[k] += 1; } return r; }; random.uint32 = function() { return random() * 0x100000000; // 2^32 }; random.fract53 = function() { return random() + (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 }; random.addNoise = function() { for (var i = arguments.length - 1; i >= 0; i--) { for (j = 0; j < 8; j++) { s[j] -= mash(arguments[i]); if (s[j] < 0) { s[j] += 1; } } } }; random.version = 'Kybos 0.9'; random.args = args; return random; } (Array.prototype.slice.call(arguments))); }; // Hugo Elias: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm var HugoEliasGenerator = function(seed) { var x; if(seed) x = seed; else x = Math.random(); this.random = function() { x = (x<<13) ^ x; x = ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); return x; } }; // test vars var seed = 17; var randomMRG32k3a = MRG32k3a(seed); var randomXorshift03 = Xorshift03(seed); var randomKISS07 = KISS07(seed); var randomLFib = LFib(seed); var randomLFIB4 = LFIB4(seed); var randomAlea = Alea(seed); var randomKybos = Kybos(seed); var randomHugo = new HugoEliasGenerator(seed); </script> Include JavaScript libraries as follows: <script src="//cdn.ext/library.js"></script> Define setup for all tests (variables, functions, arrays or other objects that will be used in the tests) (runs before each clocked test loop, outside of the timed code region) (e.g. define local test variables, reset global variables, clear canvas, etc.) (see FAQ) Define teardown for all tests (runs after each clocked test loop, outside of the timed code region) (see FAQ) Code snippets to compare Test 1 Title Async (check if this is an asynchronous test) Code randomMRG32k3a(); Test 2 Title Async (check if this is an asynchronous test) Code randomXorshift03(); Test 3 Title Async (check if this is an asynchronous test) Code randomKISS07(); Test 4 Title Async (check if this is an asynchronous test) Code randomLFib(); Test 5 Title Async (check if this is an asynchronous test) Code randomLFIB4(); Test 6 Title Async (check if this is an asynchronous test) Code randomAlea(); Test 7 Title Async (check if this is an asynchronous test) Code randomKybos(); Test 8 Title Async (check if this is an asynchronous test) Code randomHugo.random();