]> www.ginac.de Git - cln.git/blob - src/base/random/cl_UL_random.cc
Initial revision
[cln.git] / src / base / random / cl_UL_random.cc
1 // Word level random number generator.
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_random.h"
8
9
10 // Implementation.
11
12 #include "cl_low.h"
13
14 // Zufallszahlengenerator nach [Knuth: The Art of Computer Programming, Vol. II,
15 // Seminumerical Algorithms, 3.3.4., Table 1, Line 30], nach C. Haynes:
16 // X eine 64-Bit-Zahl. Iteration X := (a*X+c) mod m
17 // mit m=2^64, a=6364136223846793005, c=1.
18
19 uint32 random32 (cl_random_state& randomstate)
20 {
21 #ifdef HAVE_FAST_LONGLONG
22         // Multiplikator a=6364136223846793005 = 0x5851F42D4C957F2D :
23         var uint64 seed = highlow64(randomstate.seed.hi,randomstate.seed.lo);
24         var const uint64 a = 0x5851F42D4C957F2DUL;
25         var uint64 newseed;
26         // multiplizieren, brauche nur letzte 64 Bit:
27         mulu64(seed,a, , newseed =);
28         // c addieren:
29         newseed += 1;
30         // seed neu füllen:
31         randomstate.seed.hi = high32(newseed);
32         randomstate.seed.lo = low32(newseed);
33         // mittlere 32 Bits als Ergebnis:
34         return (uint32)(newseed >> 16);
35
36 #else
37         // Multiplikator a=6364136223846793005 = 0x5851F42D4C957F2D :
38         var uint32 seed_hi = randomstate.seed.hi;
39         var uint32 seed_lo = randomstate.seed.lo;
40         var const uint32 a_hi = 0x5851F42D;
41         var const uint32 a_lo = 0x4C957F2D;
42         var uint32 newseed_hi;
43         var uint32 newseed_lo;
44         // multiplizieren, brauche nur letzte 64 Bit:
45         mulu32(seed_lo,a_lo, newseed_hi =, newseed_lo =);
46         mulu32(seed_lo,a_hi, , newseed_hi +=);
47         mulu32(seed_hi,a_lo, , newseed_hi +=);
48         // c addieren:
49         newseed_lo += 1; if (newseed_lo==0) { newseed_hi += 1; } // um 1 erhöhen
50         // seed neu füllen:
51         randomstate.seed.hi = newseed_hi;
52         randomstate.seed.lo = newseed_lo;
53         // mittlere 32 Bits als Ergebnis:
54         return highlow32(low16(newseed_hi),high16(newseed_lo));
55 #endif
56 }