go浮点数精度损失是ieee-754二进制表示固有特性,非bug;应优先用整数运算(如“元”转“分”),必要时用decimal库并从字符串初始化,比较用a.equal(b)而非==。

Go语言中浮点数运算的精度损失不是bug,而是IEEE-754二进制表示的固有特性——像0.1、1.021、28860.000000001这类十进制小数,在二进制下是无限循环小数,必须截断存储,误差从赋值那一刻就已存在。
显示时用格式化控制精度
对用户展示结果,无需修改数值本身,只需控制输出位数:
- 用fmt.Printf("%.2f", x)显示金额、百分比等,视觉上准确且高效
- 注意:%.2f只是四舍五入显示,底层值仍是近似值,不可用于后续计算
- 避免直接fmt.Println(x)——它自动省略尾部零,掩盖了真实误差
业务逻辑中优先用整数代替浮点数
适用于金额、计数、固定小数位场景(如货币、温度、时间戳):
- 把“元”转为“分”,“米”转为“毫米”,全程用int64运算
- 例如:priceInCents := 10055(代表100.55元),total := priceInCents * 3 → 结果精确为30165分
- 最终转回展示时再除以100.0,并配合fmt.Printf格式化
必须用小数运算时选高精度十进制库
金融、计费、科学计算等不容误差的场景,别依赖float64:
- 推荐使用github.com/shopspring/decimal,支持精确十进制加减乘除和四舍五入
- 初始化务必从字符串或整数构建:decimal.RequireFromString("1.021"),而非NewFromFloat(1.021)(后者会把float64已有误差带入)
- 比较两个小数是否相等时,不用==,改用a.Equal(b)
浮点数比较和取整要显式容错
当无法避开float64时,需主动应对误差:
- 判断相等:用math.Abs(a-b) 替代a == b
- 需要四舍五入取整:用int(math.Round(x)),而非int(x)(后者是向零截断)
- 做除法时注意字面量类型:写22.0 / 7.0,别写22 / 7(否则是整数除法)
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











