返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

math 1.18

发布于 2024-10-12 19:15:55 字数 2687 浏览 0 评论 0 收藏 0

常用的是 整数浮点数 最大最小值定义。

const (
	MaxInt    = 1<<(intSize-1) - 1
	MinInt    = -1 << (intSize - 1)
	MaxInt8   = 1<<7 - 1
    MinInt8   = -1 << 7
    ...
	MaxUint64 = 1<<64 - 1
)

const (
	MaxFloat32 = 0x1p127 * (1 + (1 - 0x1p-23))
	MaxFloat64 = 0x1p1023 * (1 + (1 - 0x1p-52))
    ...
)

rand

伪随机性(pseudo random)是指一个过程似乎是随机的,但实际上并不是。

伪随机数(或称伪乱数)使用确定性算法计算出 “随机” 数序。
如种子(seed)不变,那么所返回伪随机数序也不变。优点是计算比较简单。

如注重安全,建议使用 crypto/rand 包。
或从 /dev/random/dev/urandom 读取数据进行处理。(前者会阻塞)

import (
    "math/rand"
    "time"
)

func main() {
    
    // 固定种子,导致每次输出的随机数列相同。
	// var seed int64 = 1
    
    var seed int64 = time.Now().UnixNano()
    
	rnd := rand.New(rand.NewSource(seed))
	for i := 0; i < 10; i++ {
		println(rnd.Int())
	}
}

包函数( IntIntn ...)并发安全。
如果要批量获取,建议新建 Rand 对象,减少锁定。

  • Perm :返回数列切片。(乱序)
  • Read :填充字节切片。( byte
  • Shuffle :洗牌。
package main

import (
	"math/rand"
	"fmt"
	"sort"
	"time"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

func main() {
	x := rand.Perm(10)

	c := make([]int, len(x))
	copy(c, x)
	sort.Ints(c)

	fmt.Println(x)
	fmt.Println(c)
}

// [0 2 8 7 5 9 1 4 3 6]
// [0 1 2 3 4 5 6 7 8 9]
func main() {
	b := make([]byte, 10)
	rand.Read(b)
    
	fmt.Println(b)
}

// [215 249 246 45 137 234 155 43 181 255]  以实际输出为准。
func main() {
	d := [...]int{1, 2, 3, 4, 5}
	rand.Shuffle(len(d), func(i, j int){ 
		d[i], d[j] = d[j], d[i] 
	})

	fmt.Println(d)
}

// [3 5 1 2 4]   随机,以实际输出为准。

源码剖析

随机数由 Source 生成,非并发安全。

// rand.go

func New(src Source) *Rand {
	s64, _ := src.(Source64)
	return &Rand{src: src, s64: s64}
}

func (r *Rand) Int() int {
	u := uint(r.Int63())
	return int(u << 1 >> 1) // clear sign bit if int == int32
}

func (r *Rand) Int63n(n int64) int64 {
	max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
	v := r.Int63()
	for v > max {
		v = r.Int63()
	}
	return v % n
}

有个 globalRand 为包函数提供服务,是并发安全封装。

同样需先调用 Seed 设置随机种子。

// rand.go

var globalRand = New(&lockedSource{src: NewSource(1).(*rngSource)})

func Seed(seed int64) { globalRand.Seed(seed) }
func Int() int { return globalRand.Int() }
type lockedSource struct {
	lk  sync.Mutex
	src *rngSource
}

func (r *lockedSource) Int63() (n int64) {
	r.lk.Lock()
	n = r.src.Int63()
	r.lk.Unlock()
	return
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文