对高精度数字的处理。给各位安利一个坑。我相信很多人会遇到过。

前言

大家好,本章开头先给大家说一个我毕业工作遇到的第一个坑。
公司自主开发了一个商城小程序,第一阶段大概用时2个月。我负责后端逻辑实现。我们公司不加班。
那天主管有事,半路把购买支付的逻辑代码半路扔给了我。还好,不是很难,微信文档一刷,很速度的完成了支付回调功能的逻辑处理。
就这样过了一段时间。
一天早上主管测试购买商品。因为是测试嘛,商品都是几分的,主管潇洒的清空了购物车,一共7分钱。支付完成后,尴尬了,这支付回调怎么没回来那,主管不信邪,这逻辑代码也不是我一个人写的,速度的又购买了一批6分的钱的货,支付回调又通了。这下轮到我俩懵逼了。日志一打,好啊,这7分钱到微信那里就变成0.699999999999999了。我这代码一撸下来,这价格相加的精度丢失了啊。做过微信支付的都知道微信会验证付款金额和下单的金额是否一致的。这就出个坑来了。

结果

由于表事先存金额并没有按照分来存,代码逻辑基本完成的情况下,我们选择使用 PHP 内置的 BCMath 库来进行浮点数的计算。

!!BCMath 函数需要开启扩展才可以使用,传入的参数会被转为字符串进行操作,返回值依旧为字符串。可以使用 function_defined('bcadd') 来检查某一个函数是否被定义

bcadd( $numb1,$numb2,2 )
将2个高精度数字相加,保留2位小数

bccomp( $numb1,$numb2,2 )
比较2个高精度数字,小数点后2位。
如果参数1大于参数2,返回1
如果小于,返回-1
如果等于,返回0

bcdiv(...)
将2个高精度数字相除

bcmod(...)
求高精度数字余数

bcmul(...)
对2个高精度数字相乘

bcpow(...)
求高精度数字乘方

bcpowmod(...)
求高精度数字乘方求模,数论里非常常用

bcsqrt(...)
求高精度数字平方根

bcsub(...)

将两个高精度数字相减

除了使用 BCMath 函数 还可以使用 GMP 函数,同样需要开启扩展,还有 PECL 的 big_init 库,GMP 和 big_init 的处理速度相当,但是都要比 BCMath 处理速度要快,但是使用起来 BCMath 更加简便和简单。

php

为什么我可以这么的菜?

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2

这个是常识吧,不过有教训记得住

5个月前
di-gua

是的,金额 存数据库 要存最小单位

5个月前

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!