Go的math包函数只接受float64,传int会编译失败;math.Max等需显式转换;math.Round向远离零取整;Sqrt/Pow对非法输入返回NaN而非panic。

math包函数只收float64,传int就编译失败
所有math.Abs、math.Max、math.Sqrt、math.Pow等函数,参数和返回值都是float64。Go 不做隐式类型转换,传int或int64会直接报错。
-
math.Max(3, 5)→ 编译失败:cannot use 3 (type int) as type float64 - 正确写法:
math.Max(float64(a), float64(b))或字面量写成math.Max(3.0, 5.0) - 整数比较场景下,若不涉及浮点运算,用三元表达式
a > b ? a : b更干净;只有输入可能含NaN(比如来自 JSON 解析)时,才必须用math.Max
math.Round不是“四舍五入”,而是向远离零取整
math.Round在 Go 1.10+ 中实现的是 round half away from zero:2.5 → 3.0,-2.5 → -3.0。它返回float64,不是整数类型,且行为与很多人理解的“四舍五入”一致,但容易在负边界出错。
-
math.Round(-0.5)返回-1.0,不是0.0 - 想转成整数?得显式写
int(math.Round(x)),但要注意溢出:math.Round(1e20)转int64会截断 - 保留 N 位小数推荐写法:
func RoundTo(x float64, n int) float64 { p := math.Pow10(n); return math.Round(x*p) / p } - 别用
fmt.Sprintf+strconv.ParseFloat做中间计算——有分配开销、字符串解析误差,且破坏精度链
Sqrt、Pow 等函数对非法输入静默返回 NaN
math.Sqrt(-1) 不 panic,只返回 NaN;math.Pow(-2.0, 0.5) 同样是 NaN。这不是 bug,是 IEEE 754 规定,但极易导致后续逻辑静默失效。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 开方前必须校验:
if x >= 0 { math.Sqrt(x) } else { /* handle error */ } - 指数为变量时,先用
math.Modf(y)拆出整数和小数部分;若小数部分非零且底数x ,就该拒绝计算 -
NaN具有传播性:一个NaN输入,会让后续所有math运算结果都变成NaN,而程序未必崩溃——可能只是某处坐标偏移、衰减系数归零,调试时很难溯源 - 检测手段:
math.IsNaN(v)或!math.IsNaN(a) && !math.IsNaN(b)再做比较
浮点比较不能用 ==,三角函数单位是弧度
0.1 + 0.2 == 0.3 在 Go 里恒为 false,因为 float64 存储的是二进制近似值。同时,math.Sin、math.Cos 等函数默认以弧度为单位,不是角度。
立即学习“go语言免费学习笔记(深入)”;
- 替代
==的安全写法:math.Abs(a - b) ,其中 <code>epsilon按场景选(科学计算常用1e-15,UI 显示常用1e-6) - 传角度?必须先转弧度:
math.Sin(90 * math.Pi / 180),不是math.Sin(90) -
math.Pi是常量,不是函数,别加括号:math.Pi()会编译失败 - 注意浮点误差:
math.Cos(math.Pi/2)不等于0,而是约6.123e-17—— 这不是函数问题,是 IEEE 754 本身限制
事情说清了就结束。浮点数那点事,核心就两条:永远别信==,永远先想清楚NaN和负数在哪冒头。

















