16. Random Numbers
Go’s math/rand package provides pseudo-random number generation.
Random numbers are generated by a Source. Top-level functions, such as Float64 and Int, use a default shared Source that produces a deterministic sequence of values each time a program is run. Use the Seed function to initialize the default Source if different behavior is required for each run. The default Source is safe for concurrent use by multiple goroutines.
Usage: import "math/rand"
func Intn(n int) int
Intn returns, as an int, a non-negative pseudo-random number in [0,n) from the default Source. It panics if n <= 0.
func Float64() float64
Float64 returns, as a float64, a pseudo-random number in [0.0,1.0) from the default Source.
Let us look at an example:
1 package main
2
3 import (
4 "fmt"
5 "math/rand"
6 )
7
8 func main() {
9 fmt.Println(rand.Intn(500))
10 fmt.Println(rand.Float64())
11 }
In the above program, rand.Intn returns a random int n, 0 <= n < 500.
When you run the above program the output is always the same. I got 81 and 0.9405090880450124 no matter how many times I ran the program.
To make the pseudo-random generator deterministic, give it a well-known seed. To do that let us look at:
func NewSource(seed int64) Source
NewSource returns a new pseudo-random Source seeded with the given value.
Let us modify our above program as:
1 package main
2
3 import (
4 "fmt"
5 "math/rand"
6 )
7
8 func main() {
9 fmt.Print(rand.Intn(500))
10 fmt.Println(rand.Float64())
11
12 s1 := rand.NewSource(21)
13 r1 := rand.New(s1)
14 fmt.Println(r1.Intn(500))
15 fmt.Println(r1.Float64())
16 }
Now the output I get is always:
810.9405090880450124
3000.8375676569149538