diff --git a/random/mersennetwister.js b/random/mersennetwister.js index 6af13ae..21257f1 100644 --- a/random/mersennetwister.js +++ b/random/mersennetwister.js @@ -1,64 +1,20 @@ -// this program is a JavaScript version of Mersenne Twister, with concealment and encapsulation in class, -// an almost straight conversion from the original program, mt19937ar.c, -// translated by y. okada on July 17, 2006. - -// Changes by Jesse Ruderman: -// * Use intish/int32 rather than uint32 for intermediate calculations -// (see https://bugzilla.mozilla.org/show_bug.cgi?id=883748#c1) -// * Added functions for exporting/importing the entire PRNG state -// * Removed parts not needed for fuzzing - -// in this program, procedure descriptions and comments of original source code were not removed. -// lines commented with //c// were originally descriptions of c procedure. and a few following lines are appropriate JavaScript descriptions. -// lines commented with /* and */ are original comments. -// lines commented with // are additional comments in this JavaScript version. -// before using this version, create at least one instance of MersenneTwister19937 class, and initialize the each state, given below in c comments, of all the instances. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* - A C-program for MT19937, with initialization improved 2002/1/26. - Coded by Takuji Nishimura and Makoto Matsumoto. + * JavaScript version of Mersenne Twister + * + * @author Yasuharu Okada + * + */ - Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - Any feedback is very welcome. - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) -*/ - - -function MersenneTwister19937() +function MersenneTwister() { const N = 624; const M = 397; + const UPPER_MASK = 0x80000000; + const LOWER_MASK = 0x7fffffff; const MAG01 = new Int32Array([0, 0x9908b0df]); var mt = new Int32Array(N); /* the array for the state vector */ @@ -66,38 +22,50 @@ function MersenneTwister19937() this.seed = function (s) { mt[0] = s | 0; - for (mti=1; mti>> 30)) + mti; + for (mti = 1; mti < N; mti++) { + mt[mti] = Math.imul(1812433253, mt[mti - 1] ^ (mt[mti - 1] >>> 30)) + mti; } }; - this.export_state = function() { return [mt, mti]; }; - this.import_state = function(s) { mt = s[0]; mti = s[1]; }; - this.export_mta = function() { return mt; }; - this.import_mta = function(_mta) { mt = _mta; }; - this.export_mti = function() { return mti; }; - this.import_mti = function(_mti) { mti = _mti; }; + this.export_state = function() { + return [mt, mti]; + }; - function mag01(y) - { - return MAG01[y & 0x1]; - } + this.import_state = function(s) { + mt = s[0]; + mti = s[1]; + }; + + this.export_mta = function() { + return mt; + }; + + this.import_mta = function(_mta) { + mt = _mta; + }; + + this.export_mti = function() { + return mti; + }; + + this.import_mti = function(_mti) { + mti = _mti; + }; this.int32 = function () { - var y; - var kk; + var y, kk; if (mti >= N) { /* generate N words at one time */ - for (kk=0;kk>> 1) ^ mag01(y)); + for (kk = 0; kk < N-M; kk++) { + y = ((mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK)); + mt[kk] = (mt[kk+M] ^ (y >>> 1) ^ MAG01[y & 0x1]); } - for (;kk>> 1) ^ mag01(y)); + for (; kk < N-1; kk++) { + y = ((mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK)); + mt[kk] = (mt[kk+(M-N)] ^ (y >>> 1) ^ MAG01[y & 0x1]); } - y = ((mt[N-1]&0x80000000)|(mt[0]&0x7fffffff)); - mt[N-1] = (mt[M-1] ^ (y >>> 1) ^ mag01(y)); + y = ((mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK)); + mt[N-1] = (mt[M-1] ^ (y >>> 1) ^ MAG01[y & 0x1]); mti = 0; } @@ -111,4 +79,8 @@ function MersenneTwister19937() return y; }; + + this.genrand_real2 = function () { + return this.genrand_int32() * (1.0 / 4294967296.0); + } }