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