github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/stdlibs/testing/random.gno (about) 1 package testing 2 3 import ( 4 "math" 5 "time" 6 ) 7 8 // Internal state for the random number generator. 9 var x uint64 = 42 10 11 // UniformRand generates a uniformly distributed random number. 12 // It uses the linear congrential generator method to produce the random number. 13 // and the result is in the range from 0 to m-1. here, m is 32768. 14 // To produce random number in [0, m-1], repeat this method as many times as needed. 15 // [1] https://en.wikipedia.org/wiki/Linear_congruential_generator 16 func UniformRand() uint64 { 17 var a uint64 = 950213 18 var c uint64 = 12345 19 var m uint64 = 32768 20 x = x*a + c 21 return (x >> 16) % m 22 } 23 24 // _srand function sets the seed for the random number generator. 25 // This function provides an initial starting point for the sequence of random numbers. 26 func _srand(seed int64) { 27 x = uint64(seed) 28 } 29 30 // nrand function generates a number approximating a normal distribution[1]. 31 // It uses the Central Limit Theorem[2] by summing multiple uniformly distributed random numbers 32 // to approximate a normal distribution. 33 // 34 // y = Sum(k=1, K) (x_k - K/2) / sqrt(K/12) 35 // 36 // Here, K is some integer ans x_k are uniformly distributed numbers, 37 // even for K as small as 10, the approximation is quite good. 38 // [1] https://en.wikipedia.org/wiki/Normal_distribution 39 // [2] https://en.wikipedia.org/wiki/Central_limit_theorem 40 func nrand() float64 { 41 var i, K uint64 = 0, 10 42 var m uint64 = 32768 43 var y float64 = 0 44 45 for i = 0; i < K; i++ { 46 y += float64(UniformRand()) / float64(m) 47 } 48 y = (y - float64(K)/2) / math.Sqrt(float64(K)/12) 49 return y 50 } 51 52 // randRange generates a random integer between min and max (inclusive). 53 // This function leverages the UniformRand function to generate a random number in a specified range. 54 // Note: max should be greater than min. 55 func randRange(min, max int) uint64 { 56 _min := uint64(min) 57 _max := uint64(max) 58 if _min >= _max { 59 return _min 60 } 61 62 rangeSize := _max - _min + 1 63 // adjust UniformRand to fit into our range. 64 return _min + (UniformRand() % rangeSize) 65 } 66 67 func GenerateRandomBool(bias float64) bool { 68 // Modify to use fuzz's random function for generating boolean with bias 69 if bias < 0 || bias > 1 { 70 panic("bias should be in the range [0, 1]") 71 } 72 // Convert fuzz's normalized range random float [-1, 1] to [0, 1] 73 res := (nrand() + 1) / 2 74 return res > bias 75 }