最近工作中,在处理电商用户下单模块的时候,之前遗留系统保留的是三位小数。这里带来了一个问题:
如果用户的订单价格是:6.666元,那么在向支付宝或者微信发起支付时,第三方只会保留两位数,也就是用户实际付款:6.66元。
那么问题来了,支付成功第三方回调系统接口,在接口中的逻辑需要比对支付的金额,会发现 6.666≠6.66,然后后面的逻辑无法运行,处理失败。
这里引申出来的一个问题是:我们对浮点数位数保留时,该使用何种方式?
php中提供了很多种处理浮点数位数的方式。
- number_format — 以千位分隔符方式格式化一个数字
- round — 对浮点数进行四舍五入 (通过传入第三个参数,可以控制舍、入的方式)
- sprintf — Return a formatted string
- bcadd — 2个任意精度数字的加法计算
还有一种方式就是字符串截取,比如以前三位小数,现在只要两位,就把最后一位截去。
但是,这种方式千万别用,非常无耻,万一某个数据查询出来是:9999元,你把最后一位搞掉变成:999元,自己赔公司损失吧。
说完处理的方式,不得不提一下性能问题。这里由于 round
函数如果数字后面全是0的话。不能正确处理小数位数,这里就先不提.
1 | <?php |
上面的代码运行,会得到以下结果1
2
3number_format time: 0.086385011672974
bcadd time: 0.098035097122192
sprintf time: 0.069508075714111
所以通过对比,推荐使用 sprintf
来处理浮点数位数的问题。