Last active
July 30, 2023 09:35
-
-
Save psema4/6c11e96a56a63e7c7e94ae3312a93fe7 to your computer and use it in GitHub Desktop.
Simple Middle Square Weyl Sequence PRNG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Simple PRNG Based on https://en.wikipedia.org/wiki/Middle-square_method#Middle_Square_Weyl_Sequence_RNG | |
* | |
* Usage: | |
* node: | |
* var MSWS = require('msws.js'); | |
* | |
* browser: | |
* include this script in your html document | |
* | |
* both: | |
* var prng = new MSWS(); | |
* | |
* var seed = prng.getSeed(); | |
* prng.setSeet(seed); // static sequences | |
* //prng.setSeed(new Date().getTime()); // or randomize the seed | |
* | |
* var min=0, max=1000, precision=3; | |
* console.log(prng.random()); // 0f <=> 1f | |
* console.log(prng.getInt(max, min); // 0 <=> 1000 | |
* console.log(prng.getFloat(max, min); // 0f <=> 1000f | |
* console.log(prng.getFixed(precision, max, min); // 0.000 <=> 1000.000 | |
*/ | |
(function() { | |
var MSWS = (function() { | |
var MSWS = function(opts) { | |
this.x = 0; | |
this.w = 0; | |
this.s = opts && opts.seed || 0x45ad4ece; | |
this.maxPrecision = opts && opts.maxPrecision || 10; | |
}; | |
MSWS.prototype.getSeed = function() { | |
return this.s; | |
} | |
MSWS.prototype.setSeed = function(seed) { | |
this.s = seed; | |
} | |
MSWS.prototype.msws = function(max, min) { | |
var clamped = !!max | |
, done = false | |
, i = 0 | |
; | |
max = max || 1; | |
min = min || 0; | |
while (!done) { | |
i += 1; | |
this.x *= this.x; | |
this.x += (this.w += this.s); | |
this.x = (this.x>>16) | (this.x<<16); | |
this.x = (this.x < 0) ? this.x * -1 : this.x; | |
var outOfBounds = clamped && ( (this.x > max) || (min && this.x < min) ); | |
if (!clamped) { | |
done = true; | |
} else if (!outOfBounds) { | |
done = true; | |
} | |
} | |
return this.x; | |
} | |
MSWS.prototype.getInt = function(max, min) { | |
return this.msws(max, min); | |
} | |
MSWS.prototype.getFloat = function(max, min) { | |
min = min || 0; | |
max = max || 1; | |
var whole = (max === 1) ? 0 : this.getInt(max-1, min) | |
, part = this.getInt(+'1'+'0'.repeat(this.maxPrecision)) | |
, result = +whole + '.' + part | |
; | |
return result; | |
} | |
MSWS.prototype.getFixed = function(precision, max, min) { | |
precision = precision || 2; | |
min = min || 0; | |
max = max || 1; | |
precision = precision >= this.maxPrecision ? this.maxPrecision : precision; | |
return new Number(this.getFloat(max, min)).toFixed(precision); | |
} | |
MSWS.prototype.random = function() { | |
return this.getFloat(1, 0); | |
} | |
return MSWS; | |
})(); | |
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { | |
module.exports = MSWS | |
} else { | |
window.MSWS = MSWS | |
} | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* See sample-es6.js for usage | |
Note: es6 module import / export not available in node; issues summarized at | |
https://medium.com/the-node-js-collection/an-update-on-es6-modules-in-node-js-42c958b890c | |
export default class MSWS { | |
use commonjs instead | |
*/ | |
module.exports = class MSWS { | |
constructor(opts) { | |
this.x = 0; | |
this.w = 0; | |
this.s = opts && opts.seed || 0; | |
this.maxPrecision = opts && opts.maxPrecision || 10; | |
} | |
getSeed() { | |
return this.s; | |
} | |
setSeed(seed) { | |
this.s = seed; | |
} | |
getInt(max = 1, min = 0) { | |
return this._msws(max, min); | |
} | |
getFloat(max = 1, min = 0) { | |
let whole = (max === 1) ? 0 : this.getInt(max - 1, min) | |
, part = this.getInt(+'1' + ('0'.repeat(this.maxPrecision))) | |
, result = +whole + '.' + part | |
; | |
return result; | |
} | |
getFixed(precision = 2, max = 1, min = 0) { | |
precision = precision >= this.maxPrecision ? this.maxPrecision : precision; | |
return new Number(this.getFloat(max, min)).toFixed(precision); | |
} | |
random(max = 1, min = 0) { | |
return this.getFloat(max, min); | |
} | |
_msws(max = 1, min = 0) { | |
let clamped = !!max | |
, done = false | |
, i = 0 | |
; | |
while (!done) { | |
i += 1; | |
this.x *= this.x; | |
this.x += (this.w += this.s); | |
this.x = (this.x>>16) | (this.x<<16); | |
this.x = (this.x < 0) ? this.x * -1 : this.x; | |
let outOfBounds = clamped && ( (this.x > max) || (min && this.x < min) ); | |
if (!clamped) { | |
done = true; | |
} else if (!outOfBounds) { | |
done = true; | |
} | |
} | |
return this.x; | |
} | |
// cannot be called by instance | |
static versionInfo() { | |
let version = 1 | |
return `MSWS, a Middle Square Weyl Sequence prng.\nversion ${version.toFixed(2)}\n`; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Note: es6 module import / export not available in node; issues summarized at | |
https://medium.com/the-node-js-collection/an-update-on-es6-modules-in-node-js-42c958b890c | |
import MSWS from 'msws'; | |
use commonjs instead | |
*/ | |
let MSWS = require('./msws') | |
, prng = new MSWS({ seed: 3 }) | |
; | |
console.log("%s", MSWS.versionInfo()); | |
// integers | |
for (let i=0; i<10; i++) { | |
console.log("getInt(10): %d", prng.getInt(10)); | |
} | |
// floats | |
console.log("\ngetFloat(): %s", prng.getFloat()); | |
console.log("getFloat(100, 90): %s", prng.getFloat(100, 90)); | |
// fixed-precision | |
console.log("\ngetFixed(): %s", prng.getFixed()); | |
console.log("getFixed(4): %s", prng.getFixed(4)); | |
console.log("getFixed(6): %s", prng.getFixed(6)); | |
console.log("getFixed(8): %s", prng.getFixed(8)); | |
console.log("getFixed(10): %s", prng.getFixed(10)); | |
// random | |
console.log("\nrandom(): %s", prng.random()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment