github.com/xaionaro-go/rand@v0.0.0-20191005105903-aba1befc54a5/mathrand/uint32.go (about) 1 package mathrand 2 3 const ( 4 primeNumber32bit0 = 3948558707 5 primeNumber32bit1 = 1948560947 6 7 pcgMultiplier = 6364136223846793005 // see https://en.wikipedia.org/wiki/Permuted_congruential_generator 8 pcgIncrement = 1442695040888963407 // see https://en.wikipedia.org/wiki/Permuted_congruential_generator 9 ) 10 11 func rotateLeft32(x uint32, k int) uint32 { 12 return x<<k | x>>(32-k) 13 } 14 func rotateRight32(x uint32, k int) uint32 { 15 return x>>k | x<<(32-k) 16 } 17 18 // Uint32AddRotateMultiply is a fast analog of `math/rand.Uint32`. 19 // 20 // The reliability on statistical tests of this method is unknown. This is 21 // improved LCG method, so see also Uint32MultiplyAdd. 22 func (prng *PRNG) Uint32AddRotateMultiply() uint32 { 23 prng.state32[0] += primeNumber32bit1 24 prng.state32[0] = rotateLeft32(prng.state32[0], 32) 25 prng.state32[0] *= primeNumber32bit0 26 return prng.state32[0] 27 } 28 29 // Uint32MultiplyAdd is a fast (but week) analog of `math/rand.Uint32`. 30 // 31 // See also: https://en.wikipedia.org/wiki/Linear_congruential_generator 32 func (prng *PRNG) Uint32MultiplyAdd() uint32 { 33 prng.state32[0] *= primeNumber32bit0 34 prng.state32[0] += primeNumber32bit1 35 return prng.state32[0] 36 } 37 38 // Uint32AddRotate is a very fast (but weak) analog of `math/rand.Uint32`. 39 func (prng *PRNG) Uint32AddRotate() uint32 { 40 prng.state32[0] += primeNumber32bit0 41 prng.state32[0] = rotateLeft32(prng.state32[0], 32) 42 return prng.state32[0] 43 } 44 45 // Uint32AddIfShiftXOR is a very fast (but weak) analog of `math/rand.Uint32`. 46 func (prng *PRNG) Uint32AddIfShiftXOR() uint32 { 47 prng.state32[0] += primeNumber32bit1 48 if prng.state32[0]&0x02 == 0 { 49 prng.state32[0] ^= prng.state32[0] >> 16 50 } 51 return prng.state32[0] 52 } 53 54 // Uint32Xorshift is a very fast (but weak) analog of `math/rand.Uint32`. 55 // 56 // See also: https://en.wikipedia.org/wiki/Xorshift 57 func (prng *PRNG) Uint32Xorshift() uint32 { 58 prng.state32[0] ^= prng.state32[0] << 13 59 prng.state32[0] ^= prng.state32[0] >> 17 60 prng.state32[0] ^= prng.state32[0] << 5 61 return prng.state32[0] 62 } 63 64 // See also: https://en.wikipedia.org/wiki/Permuted_congruential_generator 65 func (prng *PRNG) Uint32PCG() uint32 { 66 x := prng.pcgState 67 count := int(x >> 59) 68 prng.pcgState = x*pcgMultiplier + pcgIncrement 69 x ^= x >> 18 70 return rotateRight32(uint32(x>>27), count) 71 }