textlayouter: added method to get marked text
[iv.d.git] / prng / pmc31.d
blobd4bd9c879a9855681016f4e542bc4326d3bb737b
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // Park-Miller-Carta Pseudo-Random Number Generator, based on David G. Carta paper
18 // 31 bit of randomness
19 // seed is previous result, as usual
20 module iv.prng.pmc31 /*is aliced*/;
21 import iv.alice;
24 struct PMC31 {
25 private:
26 enum si0 = 0x00aacc76u; //next step from 0x29au;
27 uint s = si0;
29 public:
30 pure nothrow @trusted @nogc:
31 enum bool isUniformRandom = true;
32 enum uint min = 0;
33 enum uint max = 0x7fff_ffffu; // 31 bit
35 enum bool empty = false;
37 this (uint s0) { pragma(inline, true); seed(s0); }
39 @property uint front () const { pragma(inline, true); return s; }
41 auto save () const { pragma(inline, true); return PMC31(s); }
43 void popFront () {
44 if (s == 0) s = si0;
45 uint lo = 16807*(s&0xffff);
46 immutable uint hi = 16807*(s>>16);
47 lo += (hi&0x7fff)<<16;
48 lo += hi>>15;
49 //if (lo > 0x7fffffff) lo -= 0x7fffffff; // should be >=, actually
50 s = (lo&0x7FFFFFFF)+(lo>>31); // same as previous code, but branch-less
53 void seed (uint s0) { pragma(inline, true); s = (s0 ? s0 : si0); }
57 version(test_pmc31) unittest {
58 static immutable uint[8] checkValues = [
59 11193462u,
60 1297438545u,
61 500674177u,
62 989963893u,
63 1767336342u,
64 1775578337u,
65 712351247u,
66 266076304u,
69 auto rng = PMC31(0);
70 foreach (ulong v; checkValues) {
71 if (v != rng.front) assert(0);
72 //import std.stdio; writeln(rng.front, "u");
73 rng.popFront();
76 // std.random test
78 import std.random : uniform;
79 auto rng = PMC31(0);
80 foreach (immutable _; 0..8) {
81 import std.stdio;
82 auto v = uniform!"[)"(0, 4, rng);
83 writeln(v, "uL");