Go整数除法向零截断,非四舍五入;float64转int也向零截断;除零运行时panic;浮点除法易精度丢失,应优先用整数运算或big.Int。

Go 里整数除法默认截断,不是四舍五入
Go 的 int / int 运算结果永远是向下取整(向零截断),比如 7 / 3 得 2,-7 / 3 得 -2。这不是 bug,是语言规范定义的行为,但很多人误以为它会四舍五入或保留小数。
如果你要的是数学意义上的“商”,又希望控制舍入方式,必须自己处理:
- 四舍五入:先转
float64算,再用math.Round,最后转回int - 向上取整(ceil):用
int(math.Ceil(float64(a) / float64(b))) - 向下取整(floor):注意
a / b对正数已是 floor,但负数不是;稳妥做法仍是走float64+math.Floor
示例:int(math.Round(float64(7)/float64(3))) → 2,int(math.Round(float64(8)/float64(3))) → 3
float64 转 int 会直接截断小数部分
Go 不允许隐式类型转换,float64 到 int 必须显式写 int(x)。这个转换永远是向零截断,不四舍五入,也不报错——哪怕 x 是 NaN 或超出 int 范围(此时行为未定义,通常得 0 或溢出值)。
立即学习“go语言免费学习笔记(深入)”;
常见踩坑点:
-
int(2.9)→2,int(-2.9)→-2(不是 -3) - 大浮点数如
1e100转int会静默溢出,建议先用math.IsInf或范围检查 - 如果想安全四舍五入,必须用
math.Round,不能只靠int()
除零 panic 在编译期不检查,运行时才暴露
Go 允许写 a / b,即使 b 是变量、值未知。编译器不会报错,但只要运行时 b == 0,就会触发 panic:runtime error: integer divide by zero。
这在函数参数、配置读取、用户输入等场景极易发生:
- 别假设分母“肯定不为零”,尤其从 JSON、flag、环境变量读来的值
- 对关键除法,加
if b == 0 { return err }比 recover 更清晰 - 测试要覆盖
b = 0分支;模糊测试(go fuzz)也容易挖出这类问题
示例错误:func div(a, b int) int { return a / b } —— 若调用 div(5, 0),程序立即终止
精度丢失常发生在 float64 表达整数时
虽然 float64 可精确表示 2⁵³ 以内的整数,但一旦参与运算(尤其是除法),就可能引入误差。比如 10000000000000001.0 / 10.0 在 float64 中无法精确表示,转成 int 后可能差 1。
真实影响场景:
- 金融计算(绝不能用 float64 做金额除法)
- ID 分片、哈希桶计算(要求严格整除)
- 时间戳微秒级除法(如纳秒转毫秒)
对策:优先用整数运算;非要用浮点时,确认数值在 math.MaxInt64 以内且无中间舍入;必要时用 big.Int 或第三方 decimal 库










