go 1.10+ 可用 math.round,返回 float64(如 math.round(3.7) 得 4.0),转 int 需显式转换并防溢出;它实现“四舍五入远离零”(math.round(-2.5) = -2.0,math.round(-0.5) = -1.0);旧版本应避免 math.floor(x+0.5),推荐条件调用 math.ceil(x-0.5) 或 math.floor(x+0.5);浮点精度限制导致 2.65 等数无法精确表示,引发舍入偏差,高精度场景应改用整数或 decimal 库。

math.Round 在 Go 1.10+ 才有,旧版本直接调用会报 undefined: math.Round —— 别急着改代码,先确认你的 Go 版本。
Go 1.10+ 直接用 math.Round,但注意它返回 float64
它不返回 int,也不做类型转换,这是最常踩的坑:
-
math.Round(3.7)返回4.0(float64),不是4(int) - 想转成整数得显式转换:
int(math.Round(x)),但要注意溢出风险(比如x是1e20) - 对负数也按“四舍五入到最近偶数”规则?不,
math.Round是向最近整数舍入,.5往上走(math.Round(-2.5)是-2.0,不是-3.0)
Go math.Floor(x + 0.5) 不可靠
常见错误写法:int(math.Floor(x + 0.5)) 看似简单,但对负数完全失效(比如 x = -1.6,加 0.5 后是 -1.1,Floor 得 -2,结果错成 -2 而非正确四舍五入的 -2?等等,这里要算清楚——其实 -1.6 四舍五入应为 -2,但 -1.4 应为 -1,而 math.Floor(-1.4 + 0.5) = math.Floor(-0.9) = -1 是对的;问题出在 -0.5 这种边界:它会变成 math.Floor(0.0) = 0.0,但 -0.5 四舍五入按惯例该进到 0 或 -1?Go 标准库的 math.Round 规定是往远离零的方向?不,它其实是“round half away from zero”,所以 math.Round(-0.5) 是 -1.0。因此手写必须模拟这个行为:
- 推荐做法:
if x - 更稳妥:用
math.Trunc配合判断小数部分,但性能略低 - 或者直接升级 Go 版本,比自己实现更省心
math.Round 的精度陷阱:浮点数本身就不精确
这不是函数的 bug,而是 IEEE 754 的宿命。例如:
fmt.Println(math.Round(2.65 * 10) / 10) // 期望 2.7,实际可能是 2.6
原因:2.65 在二进制浮点中无法精确表示,实际存的是略小于 2.65 的值,乘 10 后略小于 26.5,Round 就进了 26.0。解决思路:
- 涉及钱或高精度需求,别用
float64,改用整数单位(如 cents)或decimal类库 - 若必须用浮点,可先用
math.Round(x*1e10) / 1e10控制位数,但不能根治问题 - 测试时别写
math.Round(2.65) == 3这种断言,浮点比较永远要用误差范围
真正麻烦的从来不是调哪个函数,而是你有没有意识到:四舍五入的“标准”本身就有好几种,而浮点数连“2.65”都可能存不准。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











