github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/cybozu/xorshift.hpp (about) 1 #pragma once 2 /** 3 @file 4 @brief XorShift 5 6 @author MITSUNARI Shigeo(@herumi) 7 @author MITSUNARI Shigeo 8 */ 9 #include <cybozu/inttype.hpp> 10 #include <assert.h> 11 12 namespace cybozu { 13 14 namespace xorshift_local { 15 16 /* 17 U is uint32_t or uint64_t 18 */ 19 template<class U, class Gen> 20 void read_local(void *p, size_t n, Gen& gen, U (Gen::*f)()) 21 { 22 uint8_t *dst = static_cast<uint8_t*>(p); 23 const size_t uSize = sizeof(U); 24 assert(uSize == 4 || uSize == 8); 25 union ua { 26 U u; 27 uint8_t a[uSize]; 28 }; 29 30 while (n >= uSize) { 31 ua ua; 32 ua.u = (gen.*f)(); 33 for (size_t i = 0; i < uSize; i++) { 34 dst[i] = ua.a[i]; 35 } 36 dst += uSize; 37 n -= uSize; 38 } 39 assert(n < uSize); 40 if (n > 0) { 41 ua ua; 42 ua.u = (gen.*f)(); 43 for (size_t i = 0; i < n; i++) { 44 dst[i] = ua.a[i]; 45 } 46 } 47 } 48 49 } // xorshift_local 50 51 class XorShift { 52 uint32_t x_, y_, z_, w_; 53 public: 54 explicit XorShift(uint32_t x = 0, uint32_t y = 0, uint32_t z = 0, uint32_t w = 0) 55 { 56 init(x, y, z, w); 57 } 58 void init(uint32_t x = 0, uint32_t y = 0, uint32_t z = 0, uint32_t w = 0) 59 { 60 x_ = x ? x : 123456789; 61 y_ = y ? y : 362436069; 62 z_ = z ? z : 521288629; 63 w_ = w ? w : 88675123; 64 } 65 uint32_t get32() 66 { 67 unsigned int t = x_ ^ (x_ << 11); 68 x_ = y_; y_ = z_; z_ = w_; 69 return w_ = (w_ ^ (w_ >> 19)) ^ (t ^ (t >> 8)); 70 } 71 uint32_t operator()() { return get32(); } 72 uint64_t get64() 73 { 74 uint32_t a = get32(); 75 uint32_t b = get32(); 76 return (uint64_t(a) << 32) | b; 77 } 78 template<class T> 79 void read(bool *pb, T *p, size_t n) 80 { 81 xorshift_local::read_local(p, n * sizeof(T), *this, &XorShift::get32); 82 *pb = true; 83 } 84 template<class T> 85 size_t read(T *p, size_t n) 86 { 87 bool b; 88 read(&b, p, n); 89 (void)b; 90 return n; 91 } 92 }; 93 94 // see http://xorshift.di.unimi.it/xorshift128plus.c 95 class XorShift128Plus { 96 uint64_t s_[2]; 97 static const uint64_t seed0 = 123456789; 98 static const uint64_t seed1 = 987654321; 99 public: 100 explicit XorShift128Plus(uint64_t s0 = seed0, uint64_t s1 = seed1) 101 { 102 init(s0, s1); 103 } 104 void init(uint64_t s0 = seed0, uint64_t s1 = seed1) 105 { 106 s_[0] = s0; 107 s_[1] = s1; 108 } 109 uint32_t get32() 110 { 111 return static_cast<uint32_t>(get64()); 112 } 113 uint64_t operator()() { return get64(); } 114 uint64_t get64() 115 { 116 uint64_t s1 = s_[0]; 117 const uint64_t s0 = s_[1]; 118 s_[0] = s0; 119 s1 ^= s1 << 23; 120 s_[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); 121 return s_[1] + s0; 122 } 123 template<class T> 124 void read(bool *pb, T *p, size_t n) 125 { 126 xorshift_local::read_local(p, n * sizeof(T), *this, &XorShift128Plus::get64); 127 *pb = true; 128 } 129 template<class T> 130 size_t read(T *p, size_t n) 131 { 132 bool b; 133 read(&b, p, n); 134 (void)b; 135 return n; 136 } 137 }; 138 139 // see http://xoroshiro.di.unimi.it/xoroshiro128plus.c 140 class Xoroshiro128Plus { 141 uint64_t s_[2]; 142 static const uint64_t seed0 = 123456789; 143 static const uint64_t seed1 = 987654321; 144 uint64_t rotl(uint64_t x, unsigned int k) const 145 { 146 return (x << k) | (x >> (64 - k)); 147 } 148 public: 149 explicit Xoroshiro128Plus(uint64_t s0 = seed0, uint64_t s1 = seed1) 150 { 151 init(s0, s1); 152 } 153 void init(uint64_t s0 = seed0, uint64_t s1 = seed1) 154 { 155 s_[0] = s0; 156 s_[1] = s1; 157 } 158 uint32_t get32() 159 { 160 return static_cast<uint32_t>(get64()); 161 } 162 uint64_t operator()() { return get64(); } 163 uint64_t get64() 164 { 165 uint64_t s0 = s_[0]; 166 uint64_t s1 = s_[1]; 167 uint64_t result = s0 + s1; 168 s1 ^= s0; 169 s_[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); 170 s_[1] = rotl(s1, 36); 171 return result; 172 } 173 template<class T> 174 void read(bool *pb, T *p, size_t n) 175 { 176 xorshift_local::read_local(p, n * sizeof(T), *this, &Xoroshiro128Plus::get64); 177 *pb = true; 178 } 179 template<class T> 180 size_t read(T *p, size_t n) 181 { 182 bool b; 183 read(&b, p, n); 184 (void)b; 185 return n; 186 } 187 }; 188 189 } // cybozu