golang float 浮点数运算失真解决方案(使用第三方 decimal 包可解决)
用Golang 做金额计算或高精度数值运算时,很多开发者都会踩过 float 浮点数的“坑”。
比如执行 0.1 + 0.2,得到的结果不是预期的 0.3,而是 0.30000000000000004。
这种运算失真在支付、财务等场景中可能引发严重问题,今天就聊聊失真的根源,以及用第三方 decimal 包解决问题的完整方案。
用Golang 做金额计算或高精度数值运算时,很多开发者都会踩过 float 浮点数的“坑”。
比如执行 0.1 + 0.2,得到的结果不是预期的 0.3,而是 0.30000000000000004。
这种运算失真在支付、财务等场景中可能引发严重问题,今天就聊聊失真的根源,以及用第三方 decimal 包解决问题的完整方案。
写代码时,不少同学常用 else if 处理多条件判断,毕竟上手简单。
但随着业务逻辑迭代,当 else if 串越来越长,你会发现代码变得臃肿难维护,调试时找个条件都要翻半天。
在使用 GO 语言的 GORM 框架进行数据库开发时,我们经常会遇到需要判断当前构建的 DB 对象是否已经添加了 WHERE 条件的场景。
比如在封装通用查询函数时,要避免重复添加默认条件,或者根据是否有自定义条件来决定是否执行某些逻辑。
对方接口返回的 HTTP Body 用 GZIP 做了压缩,go 直接用 ioutil.ReadAll 读取后转 JSON,就会一直报 “invalid character ‘�’ looking for beginning of value”。
可能有人会问:“直接看代码行数不就行了,为什么要动态获取?” 其实在实际开发中,调用者信息的动态获取有很多关键场景:
日志定位:在通用日志工具中打印调用者方法名和行数,比如封装一个 LogInfo 函数,无论在哪个方法中调用,都能自动标注来源,调试时不用再逐行找日志位置;
刚接手Go项目时,遇到过一次生产环境报错——日志只打印“查询用户失败”,没有任何调用链路信息。
翻了半天代码才定位到是数据库查询的子函数抛错。
打印错误 error 日志时,仅有错误信息,没有错误代码的堆栈信息,这在问题排查上比较困难,具体代码如下