package rand

import "math/rand"

Package rand 实现了适用于模拟等任务的伪随机数生成器, 但不应用于安全敏感的工作。

随机数由 Source 生成,通常包装在 Rand 中。 这两种类型同一时间都应由单个 goroutine 使用:在多个 goroutine 之间共享需要某种形式的同步。

顶层函数,例如 Float64 和 Int, 可安全地由多个 goroutine 并发使用。

无论以何种方式设置种子,本包的输出都很容易被预测。 对于适用于安全敏感工作的随机数,请参见 crypto/rand 包。

Example
package main

import (
	"fmt"
	"math/rand"
)

func main() {
	answers := []string{
		"It is certain",
		"It is decidedly so",
		"Without a doubt",
		"Yes definitely",
		"You may rely on it",
		"As I see it yes",
		"Most likely",
		"Outlook good",
		"Yes",
		"Signs point to yes",
		"Reply hazy try again",
		"Ask again later",
		"Better not tell you now",
		"Cannot predict now",
		"Concentrate and ask again",
		"Don't count on it",
		"My reply is no",
		"My sources say no",
		"Outlook not so good",
		"Very doubtful",
	}
	fmt.Println("Magic 8-Ball says:", answers[rand.Intn(len(answers))])
}
Example (Rand)

This example shows the use of each of the methods on a *Rand. The use of the global functions is the same, without the receiver.

package main

import (
	"fmt"
	"math/rand"
	"os"
	"text/tabwriter"
)

func main() {
	// Create and seed the generator.
	// Typically a non-fixed seed should be used, such as time.Now().UnixNano().
	// Using a fixed seed will produce the same output on every run.
	r := rand.New(rand.NewSource(99))

	// The tabwriter here helps us generate aligned output.
	w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0)
	defer w.Flush()
	show := func(name string, v1, v2, v3 any) {
		fmt.Fprintf(w, "%s\t%v\t%v\t%v\n", name, v1, v2, v3)
	}

	// Float32 and Float64 values are in [0, 1).
	show("Float32", r.Float32(), r.Float32(), r.Float32())
	show("Float64", r.Float64(), r.Float64(), r.Float64())

	// ExpFloat64 values have an average of 1 but decay exponentially.
	show("ExpFloat64", r.ExpFloat64(), r.ExpFloat64(), r.ExpFloat64())

	// NormFloat64 values have an average of 0 and a standard deviation of 1.
	show("NormFloat64", r.NormFloat64(), r.NormFloat64(), r.NormFloat64())

	// Int31, Int63, and Uint32 generate values of the given width.
	// The Int method (not shown) is like either Int31 or Int63
	// depending on the size of 'int'.
	show("Int31", r.Int31(), r.Int31(), r.Int31())
	show("Int63", r.Int63(), r.Int63(), r.Int63())
	show("Uint32", r.Uint32(), r.Uint32(), r.Uint32())

	// Intn, Int31n, and Int63n limit their output to be < n.
	// They do so more carefully than using r.Int()%n.
	show("Intn(10)", r.Intn(10), r.Intn(10), r.Intn(10))
	show("Int31n(10)", r.Int31n(10), r.Int31n(10), r.Int31n(10))
	show("Int63n(10)", r.Int63n(10), r.Int63n(10), r.Int63n(10))

	// Perm generates a random permutation of the numbers [0, n).
	show("Perm", r.Perm(5), r.Perm(5), r.Perm(5))
}

Output:

Float32     0.2635776           0.6358173           0.6718283
Float64     0.628605430454327   0.4504798828572669  0.9562755949377957
ExpFloat64  0.3362240648200941  1.4256072328483647  0.24354758816173044
NormFloat64 0.17233959114940064 1.577014951434847   0.04259129641113857
Int31       1501292890          1486668269          182840835
Int63       3546343826724305832 5724354148158589552 5239846799706671610
Uint32      2760229429          296659907           1922395059
Intn(10)    1                   2                   5
Int31n(10)  4                   7                   8
Int63n(10)  7                   6                   3
Perm        [1 4 2 3 0]         [4 2 1 3 0]         [1 2 4 0 3]

Index

Examples

Functions

func ExpFloat64

func ExpFloat64() float64

ExpFloat64 从默认 Source 返回一个在范围 (0, +[math.MaxFloat64]] 内服从指数分布的 float64,其速率参数 (lambda) 为 1,均值为 1/lambda (1)。 要产生具有不同速率参数的分布, 调用者可以使用以下方式调整输出:

sample = ExpFloat64() / desiredRateParameter

func Float32

func Float32() float32

Float32 从默认 Source 以 float32 返回半开区间 [0.0,1.0) 内的 一个伪随机数。

func Float64

func Float64() float64

Float64 从默认 Source 以 float64 返回半开区间 [0.0,1.0) 内的 一个伪随机数。

func Int

func Int() int

Int 从默认 Source 返回一个非负的伪随机 int。

func Int31

func Int31() int32

Int31 从默认 Source 以 int32 返回一个 非负的伪随机 31 位整数。

func Int31n

func Int31n(n int32) int32

Int31n 从默认 Source 以 int32 返回半开区间 [0,n) 内的 一个非负伪随机数。 如果 n <= 0,它会 panic。

func Int63

func Int63() int64

Int63 从默认 Source 以 int64 返回一个 非负的伪随机 63 位整数。

func Int63n

func Int63n(n int64) int64

Int63n 从默认 Source 以 int64 返回半开区间 [0,n) 内的 一个非负伪随机数。 如果 n <= 0,它会 panic。

func Intn

func Intn(n int) int

Intn 从默认 Source 以 int 返回半开区间 [0,n) 内的 一个非负伪随机数。 如果 n <= 0,它会 panic。

Example
package main

import (
	"fmt"
	"math/rand"
)

func main() {
	fmt.Println(rand.Intn(100))
	fmt.Println(rand.Intn(100))
	fmt.Println(rand.Intn(100))
}

func NormFloat64

func NormFloat64() float64

NormFloat64 从默认 Source 返回一个在范围 [-math.MaxFloat64, +[math.MaxFloat64]] 内服从 标准正态分布(均值 = 0,标准差 = 1)的 float64。 要产生不同的正态分布,调用者可以使用以下方式 调整输出:

sample = NormFloat64() * desiredStdDev + desiredMean

func Perm

func Perm(n int) []int

Perm 从默认 Source 以 n 个 int 的切片形式返回半开区间 [0,n) 内 整数的一个伪随机排列。

Example
package main

import (
	"fmt"
	"math/rand"
)

func main() {
	for _, value := range rand.Perm(3) {
		fmt.Println(value)
	}

}

Output:

1
2
0

func Read

func Read(p []byte) (n int, err error)

Read 从默认 Source 生成 len(p) 个随机字节,并将它们 写入 p。它总是返回 len(p) 和一个 nil 错误。 与 Rand.Read 方法不同,Read 可安全地并发使用。

已弃用:对于几乎所有用例,crypto/rand.Read 都更合适。 如果需要确定性的 source,请使用 math/rand/v2.ChaCha8.Read。

func Seed

func Seed(seed int64)

Seed 使用提供的种子值将默认 Source 初始化为 确定性的状态。除以 2³¹-1 后余数相同的种子值 会生成相同的伪随机序列。 与 Rand.Seed 方法不同,Seed 可安全地并发使用。

如果未调用 Seed,生成器会在程序启动时随机播种。

在 Go 1.20 之前,生成器在程序启动时会像 Seed(1) 那样播种。 要强制使用旧行为,请在程序启动时调用 Seed(1)。 或者,在调用本包中的任何函数之前, 在环境中设置 GODEBUG=randautoseed=0。

已弃用:从 Go 1.20 起,没有理由用随机值调用 Seed。 那些用已知值调用 Seed 以获得特定结果序列的程序 应使用 New(NewSource(seed)) 来获得 一个本地随机生成器。

从 Go 1.24 起 Seed 是无操作。要恢复先前的行为, 请设置 GODEBUG=randseednop=0。

func Shuffle

func Shuffle(n int, swap func(i, j int))

Shuffle 使用默认 Source 对元素的顺序进行伪随机化。 n 是元素的数量。如果 n < 0,Shuffle 会 panic。 swap 交换索引为 i 和 j 的元素。

Example
package main

import (
	"fmt"
	"math/rand"
	"strings"
)

func main() {
	words := strings.Fields("ink runs from the corners of my mouth")
	rand.Shuffle(len(words), func(i, j int) {
		words[i], words[j] = words[j], words[i]
	})
	fmt.Println(words)
}
Example (SlicesInUnison)
package main

import (
	"fmt"
	"math/rand"
)

func main() {
	numbers := []byte("12345")
	letters := []byte("ABCDE")
	// Shuffle numbers, swapping corresponding entries in letters at the same time.
	rand.Shuffle(len(numbers), func(i, j int) {
		numbers[i], numbers[j] = numbers[j], numbers[i]
		letters[i], letters[j] = letters[j], letters[i]
	})
	for i := range numbers {
		fmt.Printf("%c: %c\n", letters[i], numbers[i])
	}
}

func Uint32

func Uint32() uint32

Uint32 从默认 Source 以 uint32 返回一个 伪随机 32 位值。

func Uint64

func Uint64() uint64

Uint64 从默认 Source 以 uint64 返回一个 伪随机 64 位值。

Types

type Rand

type Rand struct {
	// contains filtered or unexported fields
}

Rand 是一个随机数来源。

func New
func New(src Source) *Rand

New 返回一个新的 Rand,它使用来自 src 的随机值 来生成其他随机值。

func (*Rand) ExpFloat64
func (r *Rand) ExpFloat64() float64

ExpFloat64 返回一个在范围 (0, +[math.MaxFloat64]] 内服从指数分布的 float64,其速率参数 (lambda) 为 1,均值为 1/lambda (1)。 要产生具有不同速率参数的分布, 调用者可以使用以下方式调整输出:

sample = ExpFloat64() / desiredRateParameter
func (*Rand) Float32
func (r *Rand) Float32() float32

Float32 以 float32 返回半开区间 [0.0,1.0) 内的一个伪随机数。

func (*Rand) Float64
func (r *Rand) Float64() float64

Float64 以 float64 返回半开区间 [0.0,1.0) 内的一个伪随机数。

func (*Rand) Int
func (r *Rand) Int() int

Int 返回一个非负的伪随机 int。

func (*Rand) Int31
func (r *Rand) Int31() int32

Int31 以 int32 返回一个非负的伪随机 31 位整数。

func (*Rand) Int31n
func (r *Rand) Int31n(n int32) int32

Int31n 以 int32 返回半开区间 [0,n) 内的一个非负伪随机数。 如果 n <= 0,它会 panic。

func (*Rand) Int63
func (r *Rand) Int63() int64

Int63 以 int64 返回一个非负的伪随机 63 位整数。

func (*Rand) Int63n
func (r *Rand) Int63n(n int64) int64

Int63n 以 int64 返回半开区间 [0,n) 内的一个非负伪随机数。 如果 n <= 0,它会 panic。

func (*Rand) Intn
func (r *Rand) Intn(n int) int

Intn 以 int 返回半开区间 [0,n) 内的一个非负伪随机数。 如果 n <= 0,它会 panic。

func (*Rand) NormFloat64
func (r *Rand) NormFloat64() float64

NormFloat64 返回一个在 范围 -math.MaxFloat64 到 +[math.MaxFloat64](含两端)内, 服从标准正态分布(均值 = 0,标准差 = 1)的 float64。 要产生不同的正态分布,调用者可以使用以下方式 调整输出:

sample = NormFloat64() * desiredStdDev + desiredMean
func (*Rand) Perm
func (r *Rand) Perm(n int) []int

Perm 以 n 个 int 的切片形式返回半开区间 [0,n) 内 整数的一个伪随机排列。

func (*Rand) Read
func (r *Rand) Read(p []byte) (n int, err error)

Read 生成 len(p) 个随机字节并将它们写入 p。它 总是返回 len(p) 和一个 nil 错误。 Read 不应与任何其他 Rand 方法并发调用。

func (*Rand) Seed
func (r *Rand) Seed(seed int64)

Seed 使用提供的种子值将生成器初始化为确定性的状态。 Seed 不应与任何其他 Rand 方法并发调用。

func (*Rand) Shuffle
func (r *Rand) Shuffle(n int, swap func(i, j int))

Shuffle 对元素的顺序进行伪随机化。 n 是元素的数量。如果 n < 0,Shuffle 会 panic。 swap 交换索引为 i 和 j 的元素。

func (*Rand) Uint32
func (r *Rand) Uint32() uint32

Uint32 以 uint32 返回一个伪随机 32 位值。

func (*Rand) Uint64
func (r *Rand) Uint64() uint64

Uint64 以 uint64 返回一个伪随机 64 位值。

type Source

type Source interface {
	Int63() int64
	Seed(seed int64)
}

Source 表示一个在范围 [0, 1<<63) 内的均匀分布 伪随机 int64 值的来源。

Source 不能安全地由多个 goroutine 并发使用。

func NewSource
func NewSource(seed int64) Source

NewSource 返回一个用给定值播种的新的伪随机 Source。 与顶层函数使用的默认 Source 不同,此 source 不能安全地 由多个 goroutine 并发使用。 返回的 Source 实现了 Source64。

type Source64

type Source64 interface {
	Source
	Uint64() uint64
}

Source64 是一种 Source,它还可以直接在 范围 [0, 1<<64) 内生成均匀分布的伪随机 uint64 值。 如果 Rand r 的底层 Source s 实现了 Source64, 那么 r.Uint64 会返回一次调用 s.Uint64 的结果, 而不是调用两次 s.Int63。

type Zipf

type Zipf struct {
	// contains filtered or unexported fields
}

Zipf 生成服从 Zipf 分布的变量。

func NewZipf
func NewZipf(r *Rand, s float64, v float64, imax uint64) *Zipf

NewZipf 返回一个 Zipf 变量生成器。 该生成器生成值 k ∈ [0, imax], 使得 P(k) 与 (v + k) ** (-s) 成正比。 要求:s > 1 且 v >= 1。

func (*Zipf) Uint64
func (z *Zipf) Uint64() uint64

Uint64 返回一个从 Zipf 对象所描述的 Zipf 分布中抽取的值。

Directories

v2 Package rand 实现了适用于模拟等任务的伪随机数生成器, 但不应用于安全敏感的工作。