gKit2 light
rng.h
Go to the documentation of this file.
1 
3 
4 #ifndef _RNG_H
5 #define _RNG_H
6 
7 #include <cstdint>
8 
9 
10 template< typename UInt, UInt a, UInt c, UInt m >
11 struct RNGT
12 {
13  RNGT( ) : x(), key() { seed(123451); }
14  RNGT( const UInt s ) : x(), key() { seed(s); }
15  void seed( const UInt s ) { key= (s << 1) | 1; x= key; }
16 
17  RNGT& index( const UInt i )
18  {
19  UInt tmul= a;
20  UInt tadd= c;
21  UInt mul= 1;
22  UInt add= 0;
23 
24  UInt delta= i;
25  while(delta)
26  {
27  if(delta & 1)
28  {
29  mul= mul * tmul;
30  add= add * tmul + tadd;
31  }
32 
33  tadd= tmul * tadd + tadd;
34  tmul= tmul * tmul;
35  delta= delta >> 1;
36  }
37 
38  x= mul * key + add;
39  return *this;
40  }
41 
42  unsigned sample( ) { x= (a*x+c) % m; return unsigned(x); }
43 
44  unsigned sample_range( const unsigned range )
45  {
46  // Efficiently Generating a Number in a Range
47  // cf http://www.pcg-random.org/posts/bounded-rands.html
48  unsigned divisor= ((-range) / range) + 1; // (2^32) / range
49  if(divisor == 0) return 0;
50 
51  while(true)
52  {
53  unsigned x= sample() / divisor;
54  if(x < range) return x;
55  }
56  }
57 
58  // c++ interface, compatible avec la stl
59  unsigned operator() ( ) { return sample(); }
60  static constexpr unsigned min( ) { return 0; }
61  static constexpr unsigned max( ) { return unsigned(m-1); }
62  typedef unsigned result_type;
63 
64  // etat interne
65  UInt x;
66  UInt key;
67 };
68 
69 
70 typedef RNGT<uint32_t, 48271u, 0u, (1u << 31) -1> RNG0; // minstd constants
71 typedef RNGT<uint32_t, 1103515245u, 12345u, 1u << 31> RNG32; // glibc constants
73 
74 #endif
Definition: rng.h:12