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]
}