Go 的 math 包要求显式类型对齐,不支持自动类型转换;NaN 和 Inf 不触发 panic 但会静默污染计算,必须用 math.IsNaN 显式检查。

math 包所有函数只接受 float64,传 int 或 float32 会编译失败或静默截断——这不是设计缺陷,而是 Go 明确要求你「主动声明数值语义」。
类型必须显式对齐,别指望自动转换
Go 不会把 16 自动当 16.0,也不会把 float32(1.57) 悄悄升为 float64。写错就报错,不妥协:
-
math.Sqrt(16)❌ 编译失败:常量16是int,参数要float64 -
math.Sqrt(float32(16))❌ 类型不匹配,float32≠float64 - ✅ 正确写法:
math.Sqrt(16.0)或math.Sqrt(float64(16)) - ✅ 同理:
math.Pow(2.0, 3.0)、math.Sin(float64(π/2))
NaN 和 Inf 不抛 panic,但会悄悄污染结果
math.Sqrt(-1) 返回 NaN,math.Log(0) 返回 -Inf——它们不会中断程序,却可能让下游计算全盘失效:
-
int(math.Sqrt(-1))得到0,但没人知道它本应失败 -
NaN == NaN是false,永远别用==判断 NaN - 链式计算中,一旦出现
NaN,后续结果大概率也是NaN - ✅ 必须检查:
if math.IsNaN(result) { ... }或前置校验:if x
别滥用 math.Pow,平方/立方直接乘
math.Pow(x, 2) 看似简洁,实则比 x * x 慢 20 倍以上,还引入浮点误差:
立即学习“go语言免费学习笔记(深入)”;
-
math.Pow(2, 10)可能返回1023.9999999999999,转int就变1023 -
math.Pow(-2.0, 0.5)直接返回NaN(负数非整数幂无定义) - ✅ 小整数幂(≤ 64):手写
x * x、x * x * x或循环 - ✅ 需精确整数结果:用
big.Int.Exp;需高精度科学计算:换专用库
取整后转 int 要小心浮点误差
math.Floor、math.Ceil 返回仍是 float64,直接强制类型转换可能出错:
-
int(math.Floor(9999999999999999.0))可能因精度丢失变成10000000000000000 -
math.Floor(5.0)理论上是5.0,但某些中间计算可能让它变成4.999999999999999 - ✅ 安全做法:
int(math.Round(x))或先加小偏移再转:int(math.Floor(x + 1e-9)) - ✅ 整数比较别绕路:
if a > b { return a }比int(math.Max(float64(a), float64(b)))更快更准
最常被忽略的不是怎么用对函数,而是忘了检查 math.IsNaN——线上数值逻辑崩掉,往往就因为一个没拦住的 NaN 从开方一路流进数据库主键生成逻辑里。










