Skip to content

Go 语言 math 包使用教程

Go 语言的 math 包提供了基本的数学常量和数学函数,是进行数值计算的核心工具包。

1. 基础概念

在 Go 的 math 模块中,核心概念包括:

  • 数学常量: 如 π、e、黄金比例等重要数学常量。
  • 基本运算: 幂运算、开方、对数、三角函数等。
  • 数值处理: 取整、绝对值、最大最小值等。
  • 特殊函数: 伽马函数、贝塞尔函数等高级数学函数。
  • 浮点数处理: NaN、无穷大等特殊值的处理。

math 包的子包

Go 的 math 包还包含以下重要子包:

  • math/big: 任意精度算术运算
  • math/cmplx: 复数运算
  • math/rand: 伪随机数生成
  • math/bits: 位操作函数

为什么使用 math 包?

虽然 Go 提供了基本的算术运算符,但 math 包提供了更强大的数学计算能力:

  • 精确计算: 提供高精度的数学函数实现
  • 丰富功能: 涵盖了大部分常用的数学运算
  • 性能优化: 底层实现经过优化
  • 标准库: 稳定可靠,跨平台兼容

2. 数学常量

重要的数学常量

Go 的 math 包预定义了许多重要的数学常量:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    // 基本数学常量
    fmt.Printf("π (Pi): %.10f\n", math.Pi)
    fmt.Printf("e (自然对数底): %.10f\n", math.E)
    fmt.Printf("φ (黄金比例): %.10f\n", math.Phi)
    
    // 对数相关常量
    fmt.Printf("ln(2): %.10f\n", math.Ln2)
    fmt.Printf("ln(10): %.10f\n", math.Ln10)
    fmt.Printf("log₂(e): %.10f\n", math.Log2E)
    fmt.Printf("log₁₀(e): %.10f\n", math.Log10E)
    
    // 平方根常量
    fmt.Printf("√2: %.10f\n", math.Sqrt2)
    fmt.Printf("√e: %.10f\n", math.SqrtE)
    fmt.Printf("√π: %.10f\n", math.SqrtPi)
    fmt.Printf("√φ: %.10f\n", math.SqrtPhi)
    
    // 特殊值
    fmt.Printf("正无穷: %v\n", math.Inf(1))
    fmt.Printf("负无穷: %v\n", math.Inf(-1))
    fmt.Printf("NaN: %v\n", math.NaN())
}

运行结果:

shell
π (Pi): 3.1415926536
e (自然对数底): 2.7182818285
φ (黄金比例): 1.6180339887
ln(2): 0.6931471806
ln(10): 2.3025850930
log₂(e): 1.4426950409
log₁₀(e): 0.4342944819
√2: 1.4142135624
√e: 1.6487212707
√π: 1.7724538509
√φ: 1.2720196495
正无穷: +Inf
负无穷: -Inf
NaN: NaN

浮点数限制常量

了解浮点数的精度和范围限制:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    // float64 的限制
    fmt.Printf("float64 最大值: %e\n", math.MaxFloat64)
    fmt.Printf("float64 最小正值: %e\n", math.SmallestNonzeroFloat64)
    
    // float32 的限制
    fmt.Printf("float32 最大值: %e\n", math.MaxFloat32)
    fmt.Printf("float32 最小正值: %e\n", math.SmallestNonzeroFloat32)
    
    // 整数限制
    fmt.Printf("int8 最大值: %d\n", math.MaxInt8)
    fmt.Printf("int16 最大值: %d\n", math.MaxInt16)
    fmt.Printf("int32 最大值: %d\n", math.MaxInt32)
    fmt.Printf("int64 最大值: %d\n", math.MaxInt64)
    
    fmt.Printf("uint8 最大值: %d\n", math.MaxUint8)
    fmt.Printf("uint16 最大值: %d\n", math.MaxUint16)
    fmt.Printf("uint32 最大值: %d\n", math.MaxUint32)
    fmt.Printf("uint64 最大值: %d\n", uint64(math.MaxUint64))
}

3. 基本数学运算

幂运算和开方

常用的指数和根运算:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    x := 16.0
    y := 3.0
    
    // 幂运算
    fmt.Printf("%.1f^%.1f = %.2f\n", x, y, math.Pow(x, y))
    fmt.Printf("%.1f² = %.2f\n", x, math.Pow(x, 2))
    fmt.Printf("2^%.1f = %.2f\n", x, math.Pow(2, x))
    
    // 开方运算
    fmt.Printf("√%.1f = %.2f\n", x, math.Sqrt(x))
    fmt.Printf("∛%.1f = %.2f\n", x, math.Cbrt(x))
    
    // 特殊幂运算
    fmt.Printf("2^%.1f = %.2f\n", y, math.Exp2(y))  // 2的y次方
    fmt.Printf("10^%.1f = %.2f\n", y, math.Pow10(int(y))) // 10的y次方
    fmt.Printf("e^%.1f = %.2f\n", y, math.Exp(y))   // e的y次方
    
    // 平方根的倒数
    fmt.Printf("1/√%.1f = %.4f\n", x, 1/math.Sqrt(x))
    
    // 计算斜边长度(勾股定理)
    a, b := 3.0, 4.0
    fmt.Printf("直角三角形斜边长度 (%.1f, %.1f): %.2f\n", a, b, math.Hypot(a, b))
}

运行结果:

shell
16.0^3.0 = 4096.00
16.0² = 256.00
2^16.0 = 65536.00
√16.0 = 4.00
∛16.0 = 2.52
2^3.0 = 8.00
10^3.0 = 1000.00
e^3.0 = 20.09
1/√16.0 = 0.2500
直角三角形斜边长度 (3.0, 4.0): 5.00

对数运算

各种对数函数的使用:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    x := 100.0
    
    // 基本对数
    fmt.Printf("ln(%.1f) = %.4f\n", x, math.Log(x))      // 自然对数
    fmt.Printf("log₂(%.1f) = %.4f\n", x, math.Log2(x))   // 以2为底
    fmt.Printf("log₁₀(%.1f) = %.4f\n", x, math.Log10(x)) // 以10为底
    
    // 特殊对数函数
    y := 1.5
    fmt.Printf("ln(1 + %.1f) = %.4f\n", y, math.Log1p(y)) // ln(1+x),更精确
    
    // 验证对数和指数的关系
    original := 42.0
    logged := math.Log(original)
    restored := math.Exp(logged)
    fmt.Printf("原值: %.1f, ln后: %.4f, exp后: %.1f\n", original, logged, restored)
    
    // 实际应用:计算复合增长率
    initialValue := 1000.0
    finalValue := 2000.0
    years := 5.0
    growthRate := math.Log(finalValue/initialValue) / years
    fmt.Printf("年复合增长率: %.2f%%\n", growthRate*100)
}

4. 三角函数

基本三角函数

正弦、余弦、正切及其反函数:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    // 角度转弧度的辅助函数
    deg2rad := func(deg float64) float64 {
        return deg * math.Pi / 180
    }
    
    // 弧度转角度的辅助函数
    rad2deg := func(rad float64) float64 {
        return rad * 180 / math.Pi
    }
    
    // 常用角度的三角函数值
    angles := []float64{0, 30, 45, 60, 90}
    
    fmt.Println("角度\t弧度\t\tsin\t\tcos\t\ttan")
    fmt.Println("----\t----\t\t---\t\t---\t\t---")
    
    for _, angle := range angles {
        rad := deg2rad(angle)
        sin := math.Sin(rad)
        cos := math.Cos(rad)
        tan := math.Tan(rad)
        
        fmt.Printf("%.0f°\t%.4f\t\t%.4f\t\t%.4f\t\t", angle, rad, sin, cos)
        if math.Abs(tan) > 1000 {
            fmt.Println("∞")
        } else {
            fmt.Printf("%.4f\n", tan)
        }
    }
    
    // 反三角函数
    fmt.Println("\n反三角函数示例:")
    x := 0.5
    fmt.Printf("arcsin(%.1f) = %.2f° (%.4f rad)\n", x, rad2deg(math.Asin(x)), math.Asin(x))
    fmt.Printf("arccos(%.1f) = %.2f° (%.4f rad)\n", x, rad2deg(math.Acos(x)), math.Acos(x))
    fmt.Printf("arctan(%.1f) = %.2f° (%.4f rad)\n", x, rad2deg(math.Atan(x)), math.Atan(x))
    
    // atan2 函数 - 考虑象限的反正切
    y, x := 1.0, 1.0
    fmt.Printf("atan2(%.1f, %.1f) = %.2f° (第一象限)\n", y, x, rad2deg(math.Atan2(y, x)))
    
    y, x = 1.0, -1.0
    fmt.Printf("atan2(%.1f, %.1f) = %.2f° (第二象限)\n", y, x, rad2deg(math.Atan2(y, x)))
}

双曲函数

双曲正弦、余弦、正切函数:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    x := 1.0
    
    // 双曲函数
    fmt.Printf("sinh(%.1f) = %.4f\n", x, math.Sinh(x))
    fmt.Printf("cosh(%.1f) = %.4f\n", x, math.Cosh(x))
    fmt.Printf("tanh(%.1f) = %.4f\n", x, math.Tanh(x))
    
    // 反双曲函数
    fmt.Printf("asinh(%.1f) = %.4f\n", x, math.Asinh(x))
    fmt.Printf("acosh(%.1f) = %.4f\n", x+1, math.Acosh(x+1)) // acosh需要x>=1
    fmt.Printf("atanh(%.1f) = %.4f\n", x/2, math.Atanh(x/2)) // atanh需要|x|<1
    
    // 验证双曲函数恒等式: cosh²(x) - sinh²(x) = 1
    cosh := math.Cosh(x)
    sinh := math.Sinh(x)
    identity := cosh*cosh - sinh*sinh
    fmt.Printf("验证恒等式 cosh²(%.1f) - sinh²(%.1f) = %.6f\n", x, x, identity)
}

5. 数值处理函数

取整和舍入

各种取整方式的使用:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    numbers := []float64{3.2, 3.7, -2.3, -2.8, 0.5, -0.5}
    
    fmt.Println("数值\t\tFloor\tCeil\tTrunc\tRound")
    fmt.Println("----\t\t-----\t----\t-----\t-----")
    
    for _, num := range numbers {
        floor := math.Floor(num)   // 向下取整
        ceil := math.Ceil(num)     // 向上取整
        trunc := math.Trunc(num)   // 截断小数部分
        round := math.Round(num)   // 四舍五入
        
        fmt.Printf("%.1f\t\t%.0f\t%.0f\t%.0f\t%.0f\n", num, floor, ceil, trunc, round)
    }
    
    // 获取小数部分和整数部分
    fmt.Println("\n分离整数和小数部分:")
    for _, num := range []float64{3.14, -2.71} {
        integer, fraction := math.Modf(num)
        fmt.Printf("%.2f = %.0f + %.2f\n", num, integer, fraction)
    }
    
    // 实际应用:价格计算
    price := 19.99
    taxRate := 0.08
    totalPrice := price * (1 + taxRate)
    
    fmt.Printf("\n价格计算示例:\n")
    fmt.Printf("商品价格: $%.2f\n", price)
    fmt.Printf("税率: %.1f%%\n", taxRate*100)
    fmt.Printf("含税价格: $%.2f\n", totalPrice)
    fmt.Printf("四舍五入到分: $%.2f\n", math.Round(totalPrice*100)/100)
}

绝对值和符号

处理数值的符号和绝对值:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    numbers := []float64{3.14, -2.71, 0, -0.0}
    
    fmt.Println("数值\t\t绝对值\t\t符号")
    fmt.Println("----\t\t------\t\t----")
    
    for _, num := range numbers {
        abs := math.Abs(num)
        sign := math.Signbit(num)
        
        fmt.Printf("%.2f\t\t%.2f\t\t", num, abs)
        if sign {
            fmt.Println("负数")
        } else {
            fmt.Println("正数")
        }
    }
    
    // Copysign - 复制符号
    fmt.Println("\nCopysign 示例:")
    x, y := 3.14, -2.0
    result := math.Copysign(x, y)
    fmt.Printf("Copysign(%.2f, %.1f) = %.2f\n", x, y, result)
    
    // 实际应用:计算两点间距离
    x1, y1 := 1.0, 2.0
    x2, y2 := 4.0, 6.0
    distance := math.Sqrt(math.Pow(math.Abs(x2-x1), 2) + math.Pow(math.Abs(y2-y1), 2))
    fmt.Printf("点(%.1f,%.1f)到点(%.1f,%.1f)的距离: %.2f\n", x1, y1, x2, y2, distance)
}

6. 最大值和最小值

比较函数

查找最大值和最小值:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    // 基本的最大值和最小值
    a, b := 3.14, 2.71
    fmt.Printf("max(%.2f, %.2f) = %.2f\n", a, b, math.Max(a, b))
    fmt.Printf("min(%.2f, %.2f) = %.2f\n", a, b, math.Min(a, b))
    
    // 处理特殊值
    fmt.Printf("max(NaN, 1.0) = %.2f\n", math.Max(math.NaN(), 1.0))
    fmt.Printf("max(+Inf, 1.0) = %v\n", math.Max(math.Inf(1), 1.0))
    
    // 实际应用:找到切片中的最大值和最小值
    numbers := []float64{3.14, 2.71, 1.41, 1.73, 2.23}
    
    if len(numbers) > 0 {
        maxVal := numbers[0]
        minVal := numbers[0]
        
        for _, num := range numbers[1:] {
            maxVal = math.Max(maxVal, num)
            minVal = math.Min(minVal, num)
        }
        
        fmt.Printf("\n数组 %v\n", numbers)
        fmt.Printf("最大值: %.2f\n", maxVal)
        fmt.Printf("最小值: %.2f\n", minVal)
        fmt.Printf("范围: %.2f\n", maxVal-minVal)
    }
    
    // 限制数值范围(clamp 函数)
    clamp := func(value, min, max float64) float64 {
        return math.Max(min, math.Min(max, value))
    }
    
    fmt.Println("\n数值范围限制示例:")
    testValues := []float64{-5, 0, 5, 10, 15}
    minRange, maxRange := 0.0, 10.0
    
    for _, val := range testValues {
        clamped := clamp(val, minRange, maxRange)
        fmt.Printf("clamp(%.0f, %.0f, %.0f) = %.0f\n", val, minRange, maxRange, clamped)
    }
}

7. 特殊函数

伽马函数和相关函数

高级数学函数的使用:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    // 伽马函数
    fmt.Println("伽马函数示例:")
    for i := 1; i <= 5; i++ {
        x := float64(i)
        gamma := math.Gamma(x)
        fmt.Printf("Γ(%.0f) = %.6f\n", x, gamma)
    }
    
    // 对数伽马函数
    x := 10.0
    logGamma, sign := math.Lgamma(x)
    fmt.Printf("ln|Γ(%.0f)| = %.6f, sign = %.0f\n", x, logGamma, sign)
    
    // 误差函数
    fmt.Println("\n误差函数示例:")
    values := []float64{0, 0.5, 1.0, 1.5, 2.0}
    for _, val := range values {
        erf := math.Erf(val)
        erfc := math.Erfc(val)
        fmt.Printf("erf(%.1f) = %.6f, erfc(%.1f) = %.6f\n", val, erf, val, erfc)
    }
    
    // J0, J1 贝塞尔函数
    fmt.Println("\n贝塞尔函数示例:")
    for _, val := range []float64{0, 1, 2, 5} {
        j0 := math.J0(val)
        j1 := math.J1(val)
        fmt.Printf("J₀(%.0f) = %.6f, J₁(%.0f) = %.6f\n", val, j0, val, j1)
    }
}

浮点数操作

处理浮点数的特殊情况:

go
package main

import (
    "fmt"
    "math"
)

func main() {
    // 检查特殊值
    values := []float64{1.0, math.Inf(1), math.Inf(-1), math.NaN(), 0.0}
    
    fmt.Println("值\t\tIsNaN\tIsInf\tIsInf(+)\tIsInf(-)")
    fmt.Println("---\t\t-----\t-----\t--------\t--------")
    
    for _, val := range values {
        isNaN := math.IsNaN(val)
        isInf := math.IsInf(val, 0)
        isPosInf := math.IsInf(val, 1)
        isNegInf := math.IsInf(val, -1)
        
        fmt.Printf("%v\t\t%v\t%v\t%v\t\t%v\n", val, isNaN, isInf, isPosInf, isNegInf)
    }
    
    // 浮点数分解
    fmt.Println("\n浮点数分解:")
    x := 3.14159
    frac, exp := math.Frexp(x)
    fmt.Printf("%.5f = %.5f × 2^%d\n", x, frac, exp)
    
    // 重新组合
    reconstructed := math.Ldexp(frac, exp)
    fmt.Printf("重新组合: %.5f × 2^%d = %.5f\n", frac, exp, reconstructed)
    
    // 获取浮点数的各个部分
    fmt.Println("\n浮点数详细信息:")
    testVal := -123.456
    fmt.Printf("原值: %f\n", testVal)
    fmt.Printf("符号位: %v\n", math.Signbit(testVal))
    
    mantissa, exponent := math.Frexp(math.Abs(testVal))
    fmt.Printf("尾数: %.10f\n", mantissa)
    fmt.Printf("指数: %d\n", exponent)
}

8. math 子包详解

math/big - 任意精度运算

处理超出标准类型范围的大数运算:

go
package main

import (
    "fmt"
    "math/big"
)

func main() {
    // 大整数运算
    fmt.Println("=== 大整数运算 ===")
    
    // 创建大整数
    a := big.NewInt(123456789)
    b := big.NewInt(987654321)
    
    // 基本运算
    sum := new(big.Int).Add(a, b)
    product := new(big.Int).Mul(a, b)
    
    fmt.Printf("a = %s\n", a.String())
    fmt.Printf("b = %s\n", b.String())
    fmt.Printf("a + b = %s\n", sum.String())
    fmt.Printf("a × b = %s\n", product.String())
    
    // 计算阶乘
    factorial := func(n int64) *big.Int {
        result := big.NewInt(1)
        for i := int64(2); i <= n; i++ {
            result.Mul(result, big.NewInt(i))
        }
        return result
    }
    
    fmt.Printf("20! = %s\n", factorial(20).String())
    
    // 大浮点数运算
    fmt.Println("\n=== 大浮点数运算 ===")
    
    // 设置精度为 100 位
    x := big.NewFloat(0).SetPrec(100)
    y := big.NewFloat(0).SetPrec(100)
    
    x.SetString("3.1415926535897932384626433832795028841971693993751")
    y.SetString("2.7182818284590452353602874713526624977572470937000")
    
    result := big.NewFloat(0).SetPrec(100)
    result.Add(x, y)
    
    fmt.Printf("π = %s\n", x.Text('f', 50))
    fmt.Printf("e = %s\n", y.Text('f', 50))
    fmt.Printf("π + e = %s\n", result.Text('f', 50))
    
    // 大有理数运算
    fmt.Println("\n=== 大有理数运算 ===")
    
    r1 := big.NewRat(1, 3)  // 1/3
    r2 := big.NewRat(2, 7)  // 2/7
    
    sum_rat := new(big.Rat).Add(r1, r2)
    product_rat := new(big.Rat).Mul(r1, r2)
    
    fmt.Printf("1/3 + 2/7 = %s\n", sum_rat.String())
    fmt.Printf("1/3 × 2/7 = %s\n", product_rat.String())
    fmt.Printf("1/3 + 2/7 = %f (浮点数近似)\n", sum_rat.Float64())
}

math/cmplx - 复数运算

处理复数的各种数学运算:

go
package main

import (
    "fmt"
    "math"
    "math/cmplx"
)

func main() {
    // 创建复数
    z1 := complex(3, 4)      // 3 + 4i
    z2 := complex(1, -2)     // 1 - 2i
    
    fmt.Printf("z1 = %.1f\n", z1)
    fmt.Printf("z2 = %.1f\n", z2)
    
    // 基本运算
    fmt.Println("\n=== 基本复数运算 ===")
    fmt.Printf("z1 + z2 = %.1f\n", z1+z2)
    fmt.Printf("z1 - z2 = %.1f\n", z1-z2)
    fmt.Printf("z1 × z2 = %.1f\n", z1*z2)
    fmt.Printf("z1 ÷ z2 = %.2f\n", z1/z2)
    
    // 复数函数
    fmt.Println("\n=== 复数函数 ===")
    fmt.Printf("abs(z1) = %.2f\n", cmplx.Abs(z1))        // 模长
    fmt.Printf("phase(z1) = %.2f rad\n", cmplx.Phase(z1)) // 幅角
    fmt.Printf("conj(z1) = %.1f\n", cmplx.Conj(z1))      // 共轭
    
    // 极坐标形式
    r, theta := cmplx.Polar(z1)
    fmt.Printf("z1 的极坐标: r=%.2f, θ=%.2f rad (%.1f°)\n", 
        r, theta, theta*180/math.Pi)
    
    // 从极坐标创建复数
    z3 := cmplx.Rect(r, theta)
    fmt.Printf("从极坐标重建: %.1f\n", z3)
    
    // 复数的指数和对数
    fmt.Println("\n=== 复数指数和对数 ===")
    fmt.Printf("exp(z1) = %.2f\n", cmplx.Exp(z1))
    fmt.Printf("log(z1) = %.2f\n", cmplx.Log(z1))
    fmt.Printf("log10(z1) = %.2f\n", cmplx.Log10(z1))
    
    // 复数的幂运算
    fmt.Printf("z1^2 = %.1f\n", cmplx.Pow(z1, complex(2, 0)))
    fmt.Printf("z1^z2 = %.2f\n", cmplx.Pow(z1, z2))
    
    // 复数的三角函数
    fmt.Println("\n=== 复数三角函数 ===")
    z := complex(1, 1)
    fmt.Printf("z = %.1f\n", z)
    fmt.Printf("sin(z) = %.2f\n", cmplx.Sin(z))
    fmt.Printf("cos(z) = %.2f\n", cmplx.Cos(z))
    fmt.Printf("tan(z) = %.2f\n", cmplx.Tan(z))
    
    // 实际应用:电路分析中的阻抗计算
    fmt.Println("\n=== 实际应用:电路阻抗 ===")
    
    // 电阻 R = 100Ω
    R := complex(100, 0)
    
    // 电感 L = 0.1H, 频率 f = 60Hz
    // XL = 2πfL
    f := 60.0
    L := 0.1
    XL := 2 * math.Pi * f * L
    inductance := complex(0, XL)
    
    // 电容 C = 10μF
    // XC = 1/(2πfC)
    C := 10e-6
    XC := 1 / (2 * math.Pi * f * C)
    capacitance := complex(0, -XC)
    
    // 总阻抗 Z = R + jXL + jXC
    totalImpedance := R + inductance + capacitance
    
    fmt.Printf("电阻: %.0fΩ\n", real(R))
    fmt.Printf("感抗: %.1f\n", imag(inductance))
    fmt.Printf("容抗: %.1f\n", imag(capacitance))
    fmt.Printf("总阻抗: %.1f Ω\n", totalImpedance)
    fmt.Printf("阻抗模长: %.1f Ω\n", cmplx.Abs(totalImpedance))
    fmt.Printf("相位角: %.1f°\n", cmplx.Phase(totalImpedance)*180/math.Pi)
}

math/rand - 随机数生成

生成各种类型的随机数:

go
package main

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

func main() {
    // 设置随机种子
    rand.Seed(time.Now().UnixNano())
    
    // 基本随机数
    fmt.Println("=== 基本随机数 ===")
    fmt.Printf("随机整数: %d\n", rand.Int())
    fmt.Printf("随机 int32: %d\n", rand.Int31())
    fmt.Printf("随机 int64: %d\n", rand.Int63())
    fmt.Printf("随机 uint32: %d\n", rand.Uint32())
    fmt.Printf("随机 uint64: %d\n", rand.Uint64())
    
    // 范围内的随机数
    fmt.Println("\n=== 范围内随机数 ===")
    fmt.Printf("0-99 的随机数: %d\n", rand.Intn(100))
    fmt.Printf("1-6 的随机数 (骰子): %d\n", rand.Intn(6)+1)
    
    // 浮点随机数
    fmt.Println("\n=== 浮点随机数 ===")
    fmt.Printf("0.0-1.0 的随机数: %.4f\n", rand.Float32())
    fmt.Printf("0.0-1.0 的随机数: %.4f\n", rand.Float64())
    
    // 正态分布随机数
    fmt.Println("\n=== 正态分布随机数 ===")
    for i := 0; i < 5; i++ {
        normal := rand.NormFloat64()
        fmt.Printf("标准正态分布: %.4f\n", normal)
    }
    
    // 指数分布随机数
    fmt.Println("\n=== 指数分布随机数 ===")
    for i := 0; i < 5; i++ {
        exp := rand.ExpFloat64()
        fmt.Printf("指数分布: %.4f\n", exp)
    }
    
    // 随机排列
    fmt.Println("\n=== 随机排列 ===")
    numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    fmt.Printf("原始数组: %v\n", numbers)
    
    // 洗牌算法
    rand.Shuffle(len(numbers), func(i, j int) {
        numbers[i], numbers[j] = numbers[j], numbers[i]
    })
    fmt.Printf("洗牌后: %v\n", numbers)
    
    // 随机选择
    fmt.Println("\n=== 随机选择 ===")
    fruits := []string{"苹果", "香蕉", "橙子", "葡萄", "草莓"}
    randomFruit := fruits[rand.Intn(len(fruits))]
    fmt.Printf("随机水果: %s\n", randomFruit)
    
    // 加权随机选择
    fmt.Println("\n=== 加权随机选择 ===")
    items := []string{"普通", "稀有", "史诗", "传说"}
    weights := []int{50, 30, 15, 5} // 权重
    
    // 计算累积权重
    totalWeight := 0
    for _, weight := range weights {
        totalWeight += weight
    }
    
    // 随机选择
    randomValue := rand.Intn(totalWeight)
    currentWeight := 0
    selectedItem := ""
    
    for i, weight := range weights {
        currentWeight += weight
        if randomValue < currentWeight {
            selectedItem = items[i]
            break
        }
    }
    
    fmt.Printf("加权随机选择: %s (权重: %v)\n", selectedItem, weights)
    
    // 创建自定义随机数生成器
    fmt.Println("\n=== 自定义随机数生成器 ===")
    source := rand.NewSource(12345) // 固定种子
    customRand := rand.New(source)
    
    fmt.Println("使用固定种子的随机数序列:")
    for i := 0; i < 5; i++ {
        fmt.Printf("  %d\n", customRand.Intn(100))
    }
}

math/bits - 位操作

高效的位级操作函数:

go
package main

import (
    "fmt"
    "math/bits"
)

func main() {
    x := uint64(0b11010110) // 214 in decimal
    
    fmt.Printf("x = %d (二进制: %08b)\n", x, x)
    
    // 位计数
    fmt.Println("\n=== 位计数 ===")
    fmt.Printf("前导零个数: %d\n", bits.LeadingZeros64(x))
    fmt.Printf("尾随零个数: %d\n", bits.TrailingZeros64(x))
    fmt.Printf("1的个数: %d\n", bits.OnesCount64(x))
    
    // 位长度
    fmt.Printf("位长度: %d\n", bits.Len64(x))
    
    // 位反转
    fmt.Println("\n=== 位操作 ===")
    reversed := bits.Reverse64(x)
    fmt.Printf("位反转: %064b\n", reversed)
    
    // 字节反转
    byteReversed := bits.ReverseBytes64(x)
    fmt.Printf("字节反转: %d (二进制: %064b)\n", byteReversed, byteReversed)
    
    // 循环左移和右移
    fmt.Println("\n=== 循环移位 ===")
    leftRotated := bits.RotateLeft64(x, 2)
    rightRotated := bits.RotateLeft64(x, -2) // 等价于右移2位
    
    fmt.Printf("原值:     %08b\n", x)
    fmt.Printf("左移2位:  %08b (%d)\n", leftRotated, leftRotated)
    fmt.Printf("右移2位:  %08b (%d)\n", rightRotated, rightRotated)
    
    // 加法和乘法的进位检测
    fmt.Println("\n=== 进位检测 ===")
    a, b := uint64(0xFFFFFFFFFFFFFFFF), uint64(1)
    sum, carry := bits.Add64(a, b, 0)
    fmt.Printf("%d + %d = %d, 进位: %d\n", a, b, sum, carry)
    
    // 乘法
    high, low := bits.Mul64(0xFFFFFFFF, 0xFFFFFFFF)
    fmt.Printf("0xFFFFFFFF × 0xFFFFFFFF = 0x%X%016X\n", high, low)
    
    // 除法
    quo, rem := bits.Div64(high, low, 0xFFFFFFFF)
    fmt.Printf("除法结果: 商=%d, 余数=%d\n", quo, rem)
    
    // 实际应用:快速幂运算
    fmt.Println("\n=== 实际应用:快速幂运算 ===")
    
    fastPow := func(base, exp uint64) uint64 {
        result := uint64(1)
        for exp > 0 {
            if exp&1 == 1 {
                result *= base
            }
            base *= base
            exp >>= 1
        }
        return result
    }
    
    base, exp := uint64(2), uint64(10)
    result := fastPow(base, exp)
    fmt.Printf("%d^%d = %d\n", base, exp, result)
    
    // 位操作优化的算法
    fmt.Println("\n=== 位操作算法 ===")
    
    // 检查是否为2的幂
    isPowerOfTwo := func(n uint64) bool {
        return n > 0 && (n&(n-1)) == 0
    }
    
    testNumbers := []uint64{1, 2, 3, 4, 8, 15, 16, 32}
    for _, num := range testNumbers {
        fmt.Printf("%d 是2的幂: %v\n", num, isPowerOfTwo(num))
    }
    
    // 计算下一个2的幂
    nextPowerOfTwo := func(n uint64) uint64 {
        if n == 0 {
            return 1
        }
        return 1 << bits.Len64(n-1)
    }
    
    fmt.Println("\n下一个2的幂:")
    for _, num := range []uint64{5, 7, 9, 15, 17} {
        next := nextPowerOfTwo(num)
        fmt.Printf("%d -> %d\n", num, next)
    }
}

9. 实际应用场景

科学计算示例

使用 math 包进行科学计算:

go
package main

import (
    "fmt"
    "math"
)

// 物理常量
const (
    SpeedOfLight = 299792458.0      // 光速 (m/s)
    Gravity      = 9.80665          // 重力加速度 (m/s²)
    PlanckConst  = 6.62607015e-34   // 普朗克常数 (J⋅s)
)

// 计算自由落体运动
func freeFall(height, time float64) (position, velocity float64) {
    // s = h - (1/2)gt²
    position = height - 0.5*Gravity*math.Pow(time, 2)
    // v = gt
    velocity = Gravity * time
    return
}

// 计算抛物线运动
func projectileMotion(v0, angle, t float64) (x, y, vx, vy float64) {
    angleRad := angle * math.Pi / 180
    
    // 水平位移和速度
    x = v0 * math.Cos(angleRad) * t
    vx = v0 * math.Cos(angleRad)
    
    // 垂直位移和速度
    y = v0*math.Sin(angleRad)*t - 0.5*Gravity*math.Pow(t, 2)
    vy = v0*math.Sin(angleRad) - Gravity*t
    
    return
}

// 计算复利
func compoundInterest(principal, rate float64, years int, compoundingFreq int) float64 {
    // A = P(1 + r/n)^(nt)
    return principal * math.Pow(1+rate/float64(compoundingFreq), float64(compoundingFreq*years))
}

func main() {
    fmt.Println("=== 物理计算示例 ===")
    
    // 自由落体
    height := 100.0 // 米
    time := 3.0     // 秒
    pos, vel := freeFall(height, time)
    fmt.Printf("从%.0f米高度自由落体%.0f秒后:\n", height, time)
    fmt.Printf("  位置: %.2f\n", pos)
    fmt.Printf("  速度: %.2f米/秒\n", vel)
    
    // 抛物线运动
    fmt.Println("\n抛物线运动:")
    v0 := 50.0  // 初始速度 m/s
    angle := 45.0 // 发射角度
    t := 2.0    // 时间
    
    x, y, vx, vy := projectileMotion(v0, angle, t)
    fmt.Printf("初速度%.0f m/s,角度%.0f°,%.0f秒后:\n", v0, angle, t)
    fmt.Printf("  水平位置: %.2f\n", x)
    fmt.Printf("  垂直位置: %.2f\n", y)
    fmt.Printf("  水平速度: %.2f m/s\n", vx)
    fmt.Printf("  垂直速度: %.2f m/s\n", vy)
    
    fmt.Println("\n=== 金融计算示例 ===")
    
    // 复利计算
    principal := 10000.0 // 本金
    rate := 0.05        // 年利率 5%
    years := 10         // 年数
    freq := 12          // 每年复利12次(月复利)
    
    amount := compoundInterest(principal, rate, years, freq)
    fmt.Printf("本金: $%.2f\n", principal)
    fmt.Printf("年利率: %.1f%%\n", rate*100)
    fmt.Printf("投资期: %d\n", years)
    fmt.Printf("复利频率: 每年%d\n", freq)
    fmt.Printf("最终金额: $%.2f\n", amount)
    fmt.Printf("收益: $%.2f\n", amount-principal)
    
    // 贷款月供计算
    fmt.Println("\n贷款月供计算:")
    loanAmount := 300000.0  // 贷款金额
    annualRate := 0.04      // 年利率 4%
    loanYears := 30         // 贷款年限
    
    monthlyRate := annualRate / 12
    numPayments := float64(loanYears * 12)
    
    // 月供公式: M = P * [r(1+r)^n] / [(1+r)^n - 1]
    monthlyPayment := loanAmount * (monthlyRate * math.Pow(1+monthlyRate, numPayments)) / 
                     (math.Pow(1+monthlyRate, numPayments) - 1)
    
    totalPayment := monthlyPayment * numPayments
    totalInterest := totalPayment - loanAmount
    
    fmt.Printf("贷款金额: $%.2f\n", loanAmount)
    fmt.Printf("年利率: %.1f%%\n", annualRate*100)
    fmt.Printf("贷款期限: %d\n", loanYears)
    fmt.Printf("月供: $%.2f\n", monthlyPayment)
    fmt.Printf("总还款: $%.2f\n", totalPayment)
    fmt.Printf("总利息: $%.2f\n", totalInterest)
}

数据分析工具

创建简单的统计分析工具:

go
package main

import (
    "fmt"
    "math"
    "sort"
)

// Statistics 统计数据结构
type Statistics struct {
    Data []float64
}

// NewStatistics 创建新的统计对象
func NewStatistics(data []float64) *Statistics {
    // 复制数据以避免修改原始切片
    dataCopy := make([]float64, len(data))
    copy(dataCopy, data)
    return &Statistics{Data: dataCopy}
}

// Mean 计算平均值
func (s *Statistics) Mean() float64 {
    if len(s.Data) == 0 {
        return 0
    }
    
    sum := 0.0
    for _, value := range s.Data {
        sum += value
    }
    return sum / float64(len(s.Data))
}

// Median 计算中位数
func (s *Statistics) Median() float64 {
    if len(s.Data) == 0 {
        return 0
    }
    
    sorted := make([]float64, len(s.Data))
    copy(sorted, s.Data)
    sort.Float64s(sorted)
    
    n := len(sorted)
    if n%2 == 0 {
        return (sorted[n/2-1] + sorted[n/2]) / 2
    }
    return sorted[n/2]
}

// Mode 计算众数
func (s *Statistics) Mode() []float64 {
    if len(s.Data) == 0 {
        return nil
    }
    
    frequency := make(map[float64]int)
    for _, value := range s.Data {
        frequency[value]++
    }
    
    maxFreq := 0
    for _, freq := range frequency {
        if freq > maxFreq {
            maxFreq = freq
        }
    }
    
    var modes []float64
    for value, freq := range frequency {
        if freq == maxFreq {
            modes = append(modes, value)
        }
    }
    
    sort.Float64s(modes)
    return modes
}

// Variance 计算方差
func (s *Statistics) Variance() float64 {
    if len(s.Data) <= 1 {
        return 0
    }
    
    mean := s.Mean()
    sumSquaredDiff := 0.0
    
    for _, value := range s.Data {
        diff := value - mean
        sumSquaredDiff += diff * diff
    }
    
    return sumSquaredDiff / float64(len(s.Data)-1) // 样本方差
}

// StandardDeviation 计算标准差
func (s *Statistics) StandardDeviation() float64 {
    return math.Sqrt(s.Variance())
}

// Range 计算极差
func (s *Statistics) Range() (min, max, rangeVal float64) {
    if len(s.Data) == 0 {
        return 0, 0, 0
    }
    
    min = s.Data[0]
    max = s.Data[0]
    
    for _, value := range s.Data {
        if value < min {
            min = value
        }
        if value > max {
            max = value
        }
    }
    
    rangeVal = max - min
    return
}

// Percentile 计算百分位数
func (s *Statistics) Percentile(p float64) float64 {
    if len(s.Data) == 0 || p < 0 || p > 100 {
        return 0
    }
    
    sorted := make([]float64, len(s.Data))
    copy(sorted, s.Data)
    sort.Float64s(sorted)
    
    if p == 100 {
        return sorted[len(sorted)-1]
    }
    
    index := p / 100 * float64(len(sorted)-1)
    lower := int(math.Floor(index))
    upper := int(math.Ceil(index))
    
    if lower == upper {
        return sorted[lower]
    }
    
    weight := index - float64(lower)
    return sorted[lower]*(1-weight) + sorted[upper]*weight
}

// ZScore 计算Z分数
func (s *Statistics) ZScore(value float64) float64 {
    mean := s.Mean()
    std := s.StandardDeviation()
    
    if std == 0 {
        return 0
    }
    
    return (value - mean) / std
}

func main() {
    // 示例数据:学生考试成绩
    scores := []float64{85, 92, 78, 96, 85, 88, 76, 89, 92, 84, 90, 87, 83, 91, 79}
    
    stats := NewStatistics(scores)
    
    fmt.Println("=== 学生成绩统计分析 ===")
    fmt.Printf("原始数据: %v\n", scores)
    fmt.Printf("数据量: %d\n", len(scores))
    
    fmt.Println("\n=== 集中趋势 ===")
    fmt.Printf("平均分: %.2f\n", stats.Mean())
    fmt.Printf("中位数: %.2f\n", stats.Median())
    fmt.Printf("众数: %v\n", stats.Mode())
    
    fmt.Println("\n=== 离散程度 ===")
    min, max, rangeVal := stats.Range()
    fmt.Printf("最低分: %.2f\n", min)
    fmt.Printf("最高分: %.2f\n", max)
    fmt.Printf("极差: %.2f\n", rangeVal)
    fmt.Printf("方差: %.2f\n", stats.Variance())
    fmt.Printf("标准差: %.2f\n", stats.StandardDeviation())
    
    fmt.Println("\n=== 百分位数 ===")
    percentiles := []float64{25, 50, 75, 90, 95}
    for _, p := range percentiles {
        value := stats.Percentile(p)
        fmt.Printf("第%.0f百分位数: %.2f\n", p, value)
    }
    
    fmt.Println("\n=== Z分数分析 ===")
    testScores := []float64{95, 85, 75}
    for _, score := range testScores {
        z := stats.ZScore(score)
        fmt.Printf("成绩%.0f的Z分数: %.2f", score, z)
        if math.Abs(z) > 2 {
            fmt.Printf(" (异常值)")
        }
        fmt.Println()
    }
    
    // 正态分布检验(简化版)
    fmt.Println("\n=== 分布特征 ===")
    mean := stats.Mean()
    std := stats.StandardDeviation()
    
    // 计算偏度(简化)
    sumCubedDiff := 0.0
    for _, value := range scores {
        diff := (value - mean) / std
        sumCubedDiff += diff * diff * diff
    }
    skewness := sumCubedDiff / float64(len(scores))
    
    fmt.Printf("偏度: %.3f", skewness)
    if math.Abs(skewness) < 0.5 {
        fmt.Printf(" (近似对称)")
    } else if skewness > 0 {
        fmt.Printf(" (右偏)")
    } else {
        fmt.Printf(" (左偏)")
    }
    fmt.Println()
    
    // 成绩等级分布
    fmt.Println("\n=== 成绩等级分布 ===")
    grades := map[string]int{"A": 0, "B": 0, "C": 0, "D": 0, "F": 0}
    
    for _, score := range scores {
        switch {
        case score >= 90:
            grades["A"]++
        case score >= 80:
            grades["B"]++
        case score >= 70:
            grades["C"]++
        case score >= 60:
            grades["D"]++
        default:
            grades["F"]++
        }
    }
    
    for grade, count := range grades {
        percentage := float64(count) / float64(len(scores)) * 100
        fmt.Printf("%s等级: %d人 (%.1f%%)\n", grade, count, percentage)
    }
}

10. 最佳实践

1. 精度和性能考虑

  • 了解浮点数的精度限制,避免直接比较浮点数
  • 对于高精度计算,使用 math/big
  • 在性能敏感的场景中,考虑使用位操作优化

2. 错误处理

  • 检查除零错误和定义域错误
  • 处理 NaN 和无穷大值
  • 验证输入参数的有效性

3. 数值稳定性

  • 避免大数减小数导致的精度损失
  • 使用数值稳定的算法实现
  • 注意累积误差的影响

4. 代码可读性

  • 使用有意义的常量名
  • 添加适当的注释说明数学公式
  • 将复杂的数学计算封装成函数

11. 总结

Go 的 math 包及其子包提供了全面的数学计算能力,主要特点包括:

  • 功能完整: 涵盖基础数学运算到高级数学函数
  • 高精度支持: math/big 提供任意精度运算
  • 复数支持: math/cmplx 提供完整的复数运算
  • 随机数生成: math/rand 提供多种分布的随机数
  • 位操作优化: math/bits 提供高效的位级操作

通过合理使用这些包,可以满足从简单计算到复杂科学计算的各种需求,是 Go 语言进行数值计算的强大工具集。