当前位置: 首页 > news >正文

Go基础:常用数学函数处理(主要是math包rand包的处理)

文章目录

    • 一、`math` 包概览
      • 1.1 重要数学常量
      • 1.2 基本四则运算与取整
      • 1.3 指数与对数函数
      • 1.4 三角函数
      • 1.5 其他实用函数
      • 1.6 浮点数处理的特殊函数
    • 二、随机数
      • 2.1 math/rand 包详解
      • 2.2 crypto/rand 包详解

一、math 包概览

Go 语言通过内置的 math 包提供了丰富的数学运算功能,它提供了一套完整、高效且标准的数学工具。这些函数都经过高度优化,性能卓越,适用于科学计算、图形学、游戏开发等众多领域。

1.1 重要数学常量

math 包中定义了许多数学常数,这些常量在科学和工程计算中非常有用。

常量描述近似值
math.Pi圆周率 π3.141592653589793
math.E自然对数的底数 e2.718281828459045
math.Phi黄金比例 φ1.618033988749895
math.Sqrt22 的平方根1.4142135623730951
math.SqrtEe 的平方根1.6487212707001282
math.SqrtPiπ 的平方根1.772453850905516
math.Ln22 的自然对数0.6931471805599453
math.Ln1010 的自然对数2.302585092994046

示例:使用数学常量

package main
import ("fmt""math"
)
func main() {// 计算一个半径为 5 的圆的周长和面积radius := 5.0circumference := 2 * math.Pi * radiusarea := math.Pi * radius * radiusfmt.Printf("半径为 %.2f 的圆:\n", radius)fmt.Printf("周长: %.4f\n", circumference) // 输出: 周长: 31.4159fmt.Printf("面积: %.4f\n", area)         // 输出: 面积: 78.5398// 使用自然对数底 efmt.Printf("自然对数的底数 e: %.10f\n", math.E) // 输出: 自然对数的底数 e: 2.7182818285
}

1.2 基本四则运算与取整

虽然 Go 的基本运算符 +, -, *, / 可以完成四则运算,但 math 包提供了更复杂的取整功能。

函数描述示例
math.Ceil(x)向上取整,返回不小于 x 的最小整数。math.Ceil(1.2) -> 2.0
math.Floor(x)向下取整,返回不大于 x 的最大整数。math.Floor(1.8) -> 1.0
math.Round(x)四舍五入到最近的整数。如果小数部分正好是 0.5,则向偶数方向舍入。math.Round(1.5) -> 2.0, math.Round(2.5) -> 2.0
math.Trunc(x)截断小数部分,返回整数部分。math.Trunc(1.8) -> 1.0

案例代码:取整函数对比

package main
import ("fmt""math"
)
func main() {x := 3.14159y := -2.718z := 2.5 // 用于测试 Round 的特殊情况fmt.Printf("原始值: x = %.5f, y = %.5f, z = %.1f\n", x, y, z)fmt.Println("--- 向上取整 ---")fmt.Printf("math.Ceil(%.5f) = %.1f\n", x, math.Ceil(x)) // 4.0fmt.Printf("math.Ceil(%.5f) = %.1f\n", y, math.Ceil(y)) // -2.0fmt.Println("--- 向下取整 ---")fmt.Printf("math.Floor(%.5f) = %.1f\n", x, math.Floor(x)) // 3.0fmt.Printf("math.Floor(%.5f) = %.1f\n", y, math.Floor(y)) // -3.0fmt.Println("--- 四舍五入 ---")fmt.Printf("math.Round(%.5f) = %.1f\n", x, math.Round(x)) // 3.0fmt.Printf("math.Round(%.5f) = %.1f\n", y, math.Round(y)) // -3.0fmt.Printf("math.Round(%.1f) = %.1f\n", z, math.Round(z)) // 2.0 (向偶数舍入)fmt.Println("--- 截断 ---")fmt.Printf("math.Trunc(%.5f) = %.1f\n", x, math.Trunc(x)) // 3.0fmt.Printf("math.Trunc(%.5f) = %.1f\n", y, math.Trunc(y)) // -2.0
}

1.3 指数与对数函数

函数描述示例
math.Pow(x, y)返回 x 的 y 次幂。math.Pow(2, 3) -> 8.0
math.Pow10(n)返回 10 的 n 次幂。math.Pow10(2) -> 100.0
math.Sqrt(x)返回 x 的平方根。math.Sqrt(16) -> 4.0
math.Cbrt(x)返回 x 的立方根。math.Cbrt(27) -> 3.0
math.Log(x)返回 x 的自然对数(底为 e)。math.Log(math.E) -> 1.0
math.Log10(x)返回 x 的常用对数(底为 10)。math.Log10(100) -> 2.0
math.Log2(x)返回 x 的二进制对数(底为 2)。math.Log2(8) -> 3.0
math.Exp(x)返回 e 的 x 次幂。math.Exp(1) -> 2.718...

案例代码:计算勾股定理和连续复利

package main
import ("fmt""math"
)
func main() {// 1. 计算直角三角形的斜边 (勾股定理: a² + b² = c²)a, b := 3.0, 4.0c_squared := math.Pow(a, 2) + math.Pow(b, 2)c := math.Sqrt(c_squared)fmt.Printf("直角边为 %.1f 和 %.1f 的斜边长度为: %.1f\n", a, b, c) // 输出: 5.0// 2. 计算连续复利 (公式: P * e^(r*t))principal := 1000.0 // 本金rate := 0.05        // 年利率time := 10.0        // 年数amount := principal * math.Exp(rate*time)fmt.Printf("本金 %.2f, 年利率 %.2f, %d 年后的连续复利本息和为: %.2f\n", principal, rate, int(time), amount) // 输出: 1648.72
}

1.4 三角函数

所有三角函数的参数单位都是弧度,而不是角度。你可以使用 math.Pi 进行角度和弧度的转换。

  • 角度转弧度: radians = degrees * math.Pi / 180
  • 弧度转角度: degrees = radians * 180 / math.Pi
函数描述
math.Sin(x)正弦函数
math.Cos(x)余弦函数
math.Tan(x)正切函数
math.Asin(x)反正弦函数
math.Acos(x)反余弦函数
math.Atan(x)反正切函数
math.Atan2(y, x)返回 y/x 的反正切值,但它会利用两个参数的符号来确定结果的象限,比 Atan 更准确。

案例代码:计算一个 30 度角的三角函数值

package main
import ("fmt""math"
)
func main() {angleDegrees := 30.0// 将角度转换为弧度angleRadians := angleDegrees * math.Pi / 180sinVal := math.Sin(angleRadians)cosVal := math.Cos(angleRadians)tanVal := math.Tan(angleRadians)fmt.Printf("角度 %.2f 度的三角函数值:\n", angleDegrees)fmt.Printf("Sin(%.2f°) = %.4f\n", angleDegrees, sinVal) // 0.5000fmt.Printf("Cos(%.2f°) = %.4f\n", angleDegrees, cosVal) // 0.8660fmt.Printf("Tan(%.2f°) = %.4f\n", angleDegrees, tanVal) // 0.5774
}

1.5 其他实用函数

函数描述示例
math.Abs(x)返回 x 的绝对值。math.Abs(-10) -> 10.0
math.Max(x, y)返回 x 和 y 中的较大值。math.Max(1, 2) -> 2.0
math.Min(x, y)返回 x 和 y 中的较小值。math.Min(1, 2) -> 1.0
math.Mod(x, y)取余运算,返回 x/y 的浮点余数。math.Mod(10, 3) -> 1.0
math.Dim(x, y)返回 x - y 的最大值与 0 之间的数,即 max(x-y, 0)math.Dim(5, 10) -> 0.0

案例代码:在一组数字中找到最大值、最小值和绝对值

package main
import ("fmt""math"
)
func main() {numbers := []float64{-42, 3.14, 0, 98.6, -17.5}if len(numbers) == 0 {fmt.Println("切片为空")return}// 初始化最大值和最小值为切片的第一个元素maxVal := numbers[0]minVal := numbers[0]// 遍历切片,使用 math.Max 和 math.Minfor _, num := range numbers[1:] {maxVal = math.Max(maxVal, num)minVal = math.Min(minVal, num)}fmt.Printf("数字切片: %v\n", numbers)fmt.Printf("最大值: %.2f\n", maxVal) // 98.60fmt.Printf("最小值: %.2f\n", minVal) // -42.00// 计算 -42 的绝对值absVal := math.Abs(numbers[0])fmt.Printf("第一个元素 %.2f 的绝对值是: %.2f\n", numbers[0], absVal) // 42.00
}

1.6 浮点数处理的特殊函数

在浮点数运算中,可能会遇到一些特殊值,如“非数字”(Not a Number, NaN)和无穷大(Infinity)。math 包提供了处理这些情况的函数。

函数/常量描述
math.NaN()返回一个“非数字”值。
math.Inf(sign)如果 sign >= 0,返回正无穷大;否则返回负无穷大。
math.IsNaN(x)判断 x 是否为 NaN。
math.IsInf(x, sign)判断 x 是否为无穷大。sign 的含义同 math.Inf

案例代码:处理特殊浮点值

package main
import ("fmt""math"
)
func main() {// 生成特殊值nan := math.NaN()posInf := math.Inf(1)negInf := math.Inf(-1)fmt.Printf("NaN: %v, 正无穷: %v, 负无穷: %v\n", nan, posInf, negInf)// 检查特殊值fmt.Printf("nan 是否为 NaN? %t\n", math.IsNaN(nan)) // truefmt.Printf("posInf 是否为无穷大? %t\n", math.IsInf(posInf, 1)) // true// 包含 NaN 的运算result := posInf + negInffmt.Printf("正无穷 + 负无穷 = %v\n", result) // NaNfmt.Printf("result 是否为 NaN? %t\n", math.IsNaN(result)) // true// 重要:NaN 与任何值(包括它自己)比较都返回 falsefmt.Printf("nan == nan? %t\n", nan == nan) // false// 正确的判断方式是使用 math.IsNaN()
}

二、随机数

Go 语言中处理随机数主要涉及两个核心包:

  • math/rand:用于生成伪随机数。它速度快,适用于大多数非密码学安全的场景,如游戏、模拟、抽样等。
  • crypto/rand:用于生成密码学安全的随机数。它速度较慢,但随机性更高,不可预测,适用于生成密钥、盐值、会话令牌等安全敏感的场景。

2.1 math/rand 包详解

math/rand 是我们日常开发中最常用的随机数包。让我们从最基础的例子开始。

案例:模拟掷骰子

package mainimport ("fmt""math/rand""time"
)func main() {// 为了兼容性或明确性,仍然可以手动播种rand.Seed(time.Now().UnixNano())// 掷一个6面的骰子,结果范围是 [1, 6]// rand.Intn(6) 生成 [0, 5],所以我们 +1diceRoll := rand.Intn(6) + 1fmt.Printf("你掷出了: %d\n", diceRoll)// 模拟掷10次骰子fmt.Println("连续掷10次骰子:")for i := 0; i < 10; i++ {fmt.Print(rand.Intn(6)+1, " ")}fmt.Println()
}

案例:随机抽奖

package mainimport ("fmt""math/rand""time"
)func main() {rand.Seed(time.Now().UnixNano())prizes := []string{"一等奖", "二等奖", "三等奖", "谢谢参与", "优惠券"}// 随机选择一个索引,范围是 [0, len(prizes))randomIndex := rand.Intn(len(prizes))winner := prizes[randomIndex]fmt.Printf("恭喜你,抽中了: %s\n", winner)
}

2.2 crypto/rand 包详解

当你需要生成无法被预测的随机数时,crypto/rand 是唯一的选择。它的用法与 math/rand 完全不同,它不提供像 Intn() 或 Float64() 这样的便捷函数,而是专注于生成原始的随机字节流。
案例:生成一个16字节(128位)的随机密钥

package mainimport ("crypto/rand""fmt"
)func main() {key := make([]byte, 16) // 创建一个16字节的切片// 从 crypto/rand 读取随机数填充到 key 切片中// Read 是一个阻塞操作,它会等待系统收集到足够的熵n, err := rand.Read(key)if err != nil {// 在某些系统上(如某些 WebAssembly 环境或无熵源的容器),可能会失败fmt.Println("生成随机数失败:", err)return}fmt.Printf("成功读取了 %d 字节的随机数\n", n)fmt.Printf("生成的随机密钥 (十六进制): %x\n", key)
}
http://www.dtcms.com/a/409788.html

相关文章:

  • 做彩票网站被捉将受到什么惩罚北京网站建设公司制作网站
  • 沈阳小程序建设兰州seo优化
  • 低疲劳高响应!硬件软件协同:明基 RD280U 赋能创作开发,解锁新工位高效工作氛围
  • Apache Log4j2 lookup JNDI 注入漏洞(CVE-2021-44228)
  • wpf之 Popup
  • @xyflow/react:构建交互式节点流程图的完整指南
  • LinuxC++项目开发日志——基于正倒排索引的boost搜索引擎(5——通过cpp-httplib库建立网页模块)
  • 消息队列Apache Kafka教程
  • Hadess入门到实战(3) - 如何管理Npm制品
  • 【AI算法工程师的一些子路】音频大模型从入门到精通:算法工程师的成长之路
  • 透明的多级并发(行) 方式
  • 音乐网站还可以做做seo网站的公司哪家好
  • 【python3】Streamlit快速构建前端页面
  • ​FAQ: 如何在 WPF 项目中强制指定统一输出目录并确保 VS 调试正常?
  • mysql数据库学习之数据查询进阶操作(三)
  • 虚拟机下 Ubuntu 20.04 + Kubernetes 安装步骤
  • Docker nginx容器部署前端项目。
  • 基于WebAssembly的STEP文件3D在线查看器实现详解
  • 流量对网站排名的影响因素社交网站建设平台
  • 微软 Azure AI 视频翻译服务助力 JowoAI 实现短剧高效出海
  • Kotlin协程 -> Deferred.await() 完整流程图与核心源码分析
  • java-File
  • 【uniapp】uniapp+uview-ui+mixins实现搜索+上拉加载+加载动画功能:
  • 信息产业部icp备案中心网站南通网站建设南通
  • 如何把pdf转换的excell多个表格合并
  • 5 种使用 Python 自动化处理 PDF 的实用方法
  • 专业电子商务网站建设东莞网站建设兼职
  • (23)ASP.NET Core2.2 EF关系数据库建模
  • 【ArcGIS Pro微课1000例】0073:ArcGIS Pro3.5.2学习版下载及安装教程
  • flutter mixin