zoukankan      html  css  js  c++  java
  • Go 语言标准库之 math & math/rand 包

    math 包提供了基本的数学常数和数学函数,math/rand包实现了伪随机数生成器, 本文对 math 和math/rand包的常用操作进行介绍。

    math 包

    常用常数

    ☕️ 数学常数

    const (
        E   = 2.71828182845904523536028747135266249775724709369995957496696763
        Pi  = 3.14159265358979323846264338327950288419716939937510582097494459
        Phi = 1.61803398874989484820458683436563811772030917980576286213544862
    
        Sqrt2   = 1.41421356237309504880168872420969807856967187537694807317667974
        SqrtE   = 1.64872127070012814684865078781416357165377610071014801157507931
        SqrtPi  = 1.77245385090551602729816748334114518279754945612238712821380779
        SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038
    
        Ln2    = 0.693147180559945309417232121458176568075500134360255254120680009
        Log2E  = 1 / Ln2
        Ln10   = 2.30258509299404568401799145468436420760110148862877297603332790
        Log10E = 1 / Ln10
    )
    

    ⭐️ 浮点数的取值极限

    // Max 是该类型所能表示的最大有限值;SmallestNonzero 是该类型所能表示的最小非零正数值
    const (
        MaxFloat32             = 0x1p127 * (1 + (1 - 0x1p-23)) // 3.40282346638528859811704183484516925440e+38
        SmallestNonzeroFloat32 = 0x1p-126 * 0x1p-23            // 1.401298464324817070923729583289916131280e-45
    
        MaxFloat64             = 0x1p1023 * (1 + (1 - 0x1p-52)) // 1.79769313486231570814527423731704356798070e+308
        SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52            // 4.9406564584124654417656879286822137236505980e-324
    )
    

    ✏️ 整数的取值极限

    const (
        intSize = 32 << (^uint(0) >> 63) // 32 or 64
    
        MaxInt    = 1<<(intSize-1) - 1
        MinInt    = -1 << (intSize - 1)
        MaxInt8   = 1<<7 - 1
        MinInt8   = -1 << 7
        MaxInt16  = 1<<15 - 1
        MinInt16  = -1 << 15
        MaxInt32  = 1<<31 - 1
        MinInt32  = -1 << 31
        MaxInt64  = 1<<63 - 1
        MinInt64  = -1 << 63
        MaxUint   = 1<<intSize - 1
        MaxUint8  = 1<<8 - 1
        MaxUint16 = 1<<16 - 1
        MaxUint32 = 1<<32 - 1
        MaxUint64 = 1<<64 - 1
    )
    

    常用函数

    // 三角函数
    func Sin(x float64) float64               // 正弦函数
    func Asin(x float64) float64              // 反正弦函数
    func Sinh(x float64) float64              // 双曲正弦
    func Asinh(x float64) float64             // 反双曲正弦
    func Sincos(x float64) (sin, cos float64) // 一次性返回 sin,cos
    func Cos(x float64) float64               // 余弦函数
    func Acos(x float64) float64              // 反余弦函数
    func Cosh(x float64) float64              // 双曲余弦
    func Acosh(x float64) float64             // 反双曲余弦
    func Tan(x float64) float64               // 正切函数
    func Atan(x float64) float64              // 反正切函数
    func Atan2(y, x float64) float64          // 反正切函数
    func Tanh(x float64) float64              // 双曲正切
    func Atanh(x float64) float64             // 反双曲正切
    
    // 幂次函数
    func Cbrt(x float64) float64   // 立方根函数
    func Pow(x, y float64) float64 // x 的幂函数
    func Pow10(e int) float64      // 10 根的幂函数
    func Sqrt(x float64) float64   // 平方根
    func Log(x float64) float64    // 对数函数
    func Log10(x float64) float64  // 10 为底的对数函数
    func Log2(x float64) float64   // 2 为底的对数函数
    func Log1p(x float64) float64  // log(1 + x)
    func Logb(x float64) float64   // 相当于 log2(x) 的绝对值
    func Ilogb(x float64) int      // 相当于 log2(x) 的绝对值的整数部分
    func Exp(x float64) float64    // 指数函数
    func Exp2(x float64) float64   // 2 为底的指数函数
    func Expm1(x float64) float64  // Exp(x) - 1
    
    // 特殊函数
    func Inf(sign int) float64           // 如果 sign>=0 函数返回正无穷大,否则返回负无穷大
    func IsInf(f float64, sign int) bool //  如果 sign > 0,f 是正无穷大时返回真;如果 sign < 0,f 是负无穷大时返回真;sign == 0 则 f 是两种无穷大时都返回真
    func NaN() float64                   // 返回一个 NaN(Not A Number)值
    func IsNaN(f float64) (is bool)      // 是否是 NaN 值
    func Hypot(p, q float64) float64     // 计算直角三角形的斜边长
    
    // 类型转化函数
    func Float32bits(f float32) uint32     // float32 和 unit32 的转换
    func Float32frombits(b uint32) float32 // uint32 和 float32 的转换
    func Float64bits(f float64) uint64     // float64 和 uint64 的转换
    func Float64frombits(b uint64) float64 // uint64 和 float64 的转换
    
    // 其他函数
    func Abs(x float64) float64                       // 绝对值函数
    func Ceil(x float64) float64                      // 向上取整
    func Floor(x float64) float64                     // 向下取整
    func Trunc(x float64) float64                     // 截取函数(返回 x 的整数部分)
    func Mod(x, y float64) float64                    // 取模,结果的正负号和 x 相同
    func Remainder(x, y float64) float64              // 取余运算
    func Modf(f float64) (int float64, frac float64)  // 分解 f,以得到 f 的整数和小数部分
    func Frexp(f float64) (frac float64, exp int)     // 分解 f,得到 f 的位数和指数
    func Max(x, y float64) float64                    // 取大值
    func Min(x, y float64) float64                    // 取小值
    func Dim(x, y float64) float64                    // 复数的维数
    func J0(x float64) float64                        // 0 阶贝塞尔函数
    func J1(x float64) float64                        // 1 阶贝塞尔函数
    func Jn(n int, x float64) float64                 // n 阶贝塞尔函数
    func Y0(x float64) float64                        // 第二类贝塞尔函数 0 阶
    func Y1(x float64) float64                        // 第二类贝塞尔函数 1 阶
    func Yn(n int, x float64) float64                 // 第二类贝塞尔函数 n 阶
    func Erf(x float64) float64                       // 误差函数
    func Erfc(x float64) float64                      // 余补误差函数
    func Copysign(x, y float64) float64               // 以 y 的符号返回 x 值
    func Signbit(x float64) bool                      // 获取 x 的符号
    func Gamma(x float64) float64                     // 伽玛函数
    func Lgamma(x float64) (lgamma float64, sign int) // 伽玛函数的自然对数
    func Ldexp(frac float64, exp int) float64         // value 乘以 2 的 exp 次幂
    func Nextafter(x, y float64) (r float64)          // 返回参数 x 在参数 y 方向上可以表示的最接近的数值,若 x 等于 y,则返回 x
    func Nextafter32(x, y float32) (r float32)        // 返回参数 x 在参数 y 方向上可以表示的最接近的数值,若 x 等于 y,则返回 x
    

    示例代码

    package main
    
    import (
        "fmt"
        "math"
    )
    
    func main() {
        fmt.Println(math.IsNaN(math.NaN()))     // true
        fmt.Println(math.IsInf(math.Inf(1), 1)) // true
        fmt.Println(math.Ceil(1.000001))        // 2
        fmt.Println(math.Floor(1.999999))       // 1
        fmt.Println(math.Trunc(1.999999))       // 1
        fmt.Println(math.Abs(-1.3))             // 1.3
        fmt.Println(math.Max(-1.3, 0))          // 0
        fmt.Println(math.Min(-1.3, 0))          // -1.3
        fmt.Println(math.Dim(-12, 19))          // 0
        fmt.Println(math.Mod(9, 4))             // 1
        fmt.Println(math.Sqrt(9))               // 3
        fmt.Println(math.Cbrt(8))               // 2
        fmt.Println(math.Hypot(3, 4))           // 5
        fmt.Println(math.Sin(90))               // 0.893996663600558
        fmt.Println(math.Cos(0))                // 1
        fmt.Println(math.Tan(45))               // 1.6197751905438615
        fmt.Println(math.Log(1))                // 0
        fmt.Println(math.Log2(16))              // 4
        fmt.Println(math.Log10(1000))           // 3
        fmt.Println(math.Pow(2, 8))             // 256
        fmt.Println(math.Pow10(2))              // 100
    }
    

    math/rand 包

    Rand 结构体生成随机数

    Go 语言中生成随机数需要一个结构体实例Rand,该结构体字段都是隐藏或非导出,只能通过其它函数构建,该结构体定义如下:

    // Rand 生成服从多种分布的随机数
    type Rand struct {
        src Source
        s64 Source64 // non-nil if src is source64
    
        // readVal contains remainder of 63-bit integer used for bytes
        // generation during most recent Read call.
        // It is saved so next Read call can start where the previous
        // one finished.
        readVal int64
        // readPos indicates the number of low-order bytes of readVal
        // that are still valid.
        readPos int8
    }
    
    // Source 代表一个生成均匀分布在范围 [0, 1<<63) 的 int64 值的(伪随机的)资源
    type Source interface {
        Int63() int64
        Seed(seed int64)
    }
    

    ✌ 常用的方法

    // 使用给定的种子创建一个伪随机资源
    func NewSource(seed int64) Source
    
    // 返回一个使用 src 生产的随机数来生成其他各种分布的随机数值的 *Rand
    func New(src Source) *Rand
    
    // 使用给定的 seed 来初始化生成器到一个确定的状态
    func (r *Rand) Seed(seed int64)
    
    // 返回一个非负的伪随机 int 值
    func (r *Rand) Int() int
    
    // 返回一个 int32 类型的非负的 31 位伪随机数
    func (r *Rand) Int31() int32
    
    // 返回一个 int64 类型的非负的 63 位伪随机数
    func (r *Rand) Int63() int64
    
    // 返回一个 uint32 类型的非负的 32 位伪随机数
    func (r *Rand) Uint32() uint32
    
    // 返回一个 uint64 类型的非负的 64 位伪随机数
    func (r *Rand) Uint64() uint64
    
    // 返回一个取值范围在 [0,n) 的伪随机 int 值,如果 n <= 0 会 panic
    func (r *Rand) Intn(n int) int
    
    // 返回一个取值范围在 [0,n) 的伪随机 int32 值,如果 n <= 0 会 panic
    func (r *Rand) Int31n(n int32) int32
    
    // 返回一个取值范围在 [0,n) 的伪随机 int64 值,如果 n <= 0 会 panic
    func (r *Rand) Int63n(n int64) int64
    
    // 返回一个取值范围在 [0.0, 1.0) 的伪随机 float32 值
    func (r *Rand) Float32() float32
    
    // 返回一个取值范围在 [0.0, 1.0) 的伪随机 float64 值
    func (r *Rand) Float64() float64
    
    // 返回一个有 n 个元素的,[0,n) 范围内整数的伪随机排列的切片
    func (r *Rand) Perm(n int) []int
    

    ✍ 示例代码

    package main
    
    import (
        "fmt"
        "math/rand"
        "time"
    )
    
    func main() {
        // 使用当前时间的纳秒作为随机数种子,生成一个 Rand
        random := rand.New(rand.NewSource(time.Now().UnixNano()))
    
        // 产生随机数
        fmt.Println(random.Int())        // 5700972045344779666
        fmt.Println(random.Int31())      // 502460982
        fmt.Println(random.Int63())      // 4492647983110733892
        fmt.Println(random.Uint32())     // 3078962887
        fmt.Println(random.Uint64())     // 16976507327111900586
        fmt.Println(random.Intn(1000))   // 978
        fmt.Println(random.Int31n(1000)) // 864
        fmt.Println(random.Int63n(1000)) // 585
        fmt.Println(random.Float32())    // 0.23783964
        fmt.Println(random.Float64())    // 0.6970960282910409
        fmt.Println(random.Perm(5))      // [4 0 3 2 1]
    }
    

    其它生成随机数函数

    Go 语言在math/rand包中内置一个 Rand 对象 globalRand,并将该对象的方法包装为math/rand包的公开函数,我们可以直接调用这些公开函数生成随机数。

    // globalRand 对象是一个随机数种子默认为 1 的随机数生成器
    var globalRand = New(&lockedSource{src: NewSource(1).(*rngSource)})
    

    常用的函数

    // 下面函数实际上是调用 globalRand 对象的方法生成随机数
    // 设置随机数种子,如果不设置,默认为 1 
    func Seed(seed int64)
    
    // 返回一个非负的伪随机 int 值
    func Int() int
    
    // 返回一个 int32 类型的非负的 31 位伪随机数
    func Int31() int32
    
    // 返回一个 int64 类型的非负的 63 位伪随机数
    func Int63() int64
    
    // 返回一个 uint32 类型的非负的 32 位伪随机数
    func Uint32() uint32
    
    // 返回一个 uint64 类型的非负的 64 位伪随机数
    func Uint64() uint64
    
    // 返回一个取值范围在 [0,n) 的伪随机 int 值,如果 n <= 0 会 panic
    func Intn(n int) int
    
    // 返回一个取值范围在 [0,n) 的伪随机 int32 值,如果 n <= 0 会 panic
    func Int31n(n int32) int32
    
    // 返回一个取值范围在 [0, n) 的伪随机 int64 值,如果 n<=0 会 panic
    func Int63n(n int64) int64
    
    // 返回一个取值范围在 [0.0, 1.0) 的伪随机 float32 值
    func Float32() float32
    
    // 返回一个取值范围在 [0.0, 1.0) 的伪随机 float64 值
    func Float64() float64
    
    // 返回一个有 n 个元素的,[0,n) 范围内整数的伪随机排列的切片
    func Perm(n int) []int
    

    ☕️ 示例代码

    package main
    
    import (
        "fmt"
        "math/rand"
        "time"
    )
    
    func main() {
        // 使用当前时间的纳秒作为随机数种子
        rand.Seed(time.Now().UnixNano())
    
        // 产生随机数
        fmt.Println(rand.Int())        // 7696473600670801125
        fmt.Println(rand.Int31())      // 101522707
        fmt.Println(rand.Int63())      // 4586127142344489967
        fmt.Println(rand.Uint32())     // 2654323971
        fmt.Println(rand.Uint64())     // 818444552739191252
        fmt.Println(rand.Intn(1000))   // 404
        fmt.Println(rand.Int31n(1000)) // 839
        fmt.Println(rand.Int63n(1000)) // 670
        fmt.Println(rand.Float32())    // 0.045811735
        fmt.Println(rand.Float64())    // 0.22264400405223367
        fmt.Println(rand.Perm(5))      // [1 4 2 3 0]
    }
    

    参考

    1. go math/rand包详解
  • 相关阅读:
    解决Chrome 70及以上版本的证书问题:Failed to load resource: net::ERR_CERT_SYMANTEC_LEGACY
    VUE使用axios数据请求时报错 TypeError: Cannot set property 'xxxx' of undefined 的解决办法
    生辰八字推算
    OneNote巧妙设置标题
    Kibana安装与介绍
    Logstash入门简介
    Metricbeat入门简介
    FileBeats入门简介
    ElasticSearch集群部署
    ElasticSearch安装与介绍
  • 原文地址:https://www.cnblogs.com/zongmin/p/15649049.html
Copyright © 2011-2022 走看看