math包所有函数统一使用float64类型,int等需显式转换;NaN/Inf不触发panic而静默传播,须用math.IsNaN或math.IsInf主动检查。

Go 标准库 math 包提供了大量浮点数数学函数,但不支持复数、整数直接运算(如 int 类型需先转为 float64),也不处理 NaN/Inf 的传播细节——这些恰恰是实际编码中最容易出错的地方。
常用函数怎么用?参数和返回值类型必须对齐
math 所有函数统一以 float64 为输入输出类型。传入 int、int64 或 float32 都会编译报错或隐式截断,必须显式转换。
-
math.Sqrt(16)❌ 编译失败:16 是int;正确写法:math.Sqrt(16.0)或math.Sqrt(float64(16)) -
math.Pow(2, 3)❌ 同样错;应写成math.Pow(2.0, 3.0) -
math.Sin(float32(1.57))❌ 类型不匹配;必须是float64,所以得写math.Sin(float64(1.57))
处理边界值:NaN、Inf、负数开方要主动检查
math 不抛 panic,而是静默返回特殊值。比如 math.Sqrt(-1) 返回 NaN,math.Log(0) 返回 -Inf。下游若直接参与计算,可能让结果“污染”整个表达式。
- 用
math.IsNaN(x)或math.IsInf(x, 0)显式判断 -
math.Sqrt前建议加if x -
math.Log前检查x ,避免得到 <code>-Inf后再做加减导致非预期行为
package main
<p>import (
"fmt"
"math"
)</p><p>func safeSqrt(x float64) (float64, error) {
if x < 0 {
return 0, fmt.Errorf("cannot sqrt negative number: %v", x)
}
return math.Sqrt(x), nil
}</p><p>func main() {
if v, err := safeSqrt(-4); err != nil {
fmt.Println(err) // 输出:cannot sqrt negative number: -4
} else {
fmt.Println(v)
}
}精度与性能注意点:不要在热循环里反复调用 trig/log/exp
像 math.Sin、math.Exp 这类函数底层调用的是系统 libc 或软件实现,比基础四则运算慢 10–100 倍。如果输入范围有限(比如角度只在 0~360 内),考虑预计算查表;若只是判断大小关系,有时可用近似不等式替代(如用 x - x*x/2 < math.Sin(x) 粗略估计)。
立即学习“go语言免费学习笔记(深入)”;
-
math.Abs、math.Max、math.Min是轻量级,可放心用 -
math.Ceil/math.Floor对整数输入也有效,但返回仍是float64,别忘了转回int时用int(math.Floor(x))而非强制类型转换(避免浮点误差) -
math.Mod和取余操作符%行为不同:math.Mod(-5.5, 2.0)返回-1.5,而-5 % 2是-1(且仅限整数)
最常被忽略的其实是 math.Nextafter 和 math.Ulp ——它们用于测试浮点精度边界,但多数业务代码根本用不到;反过来,该检查 IsNaN 的地方没检查,才是线上数值逻辑崩掉的主因。










