利用PHP高精确度运算BC函数库解决小数计算异常问题

2017-11-05 12:40 栏目:技术开发 查看(3191)

现在开发项目,很多时候都与支付相关,而在支付流程中就必然牵扯到金额的计算,在现实生活中商品的价格不一定都是整数,标准的价格是两位小数精确到分。比如11.20、32.30、9.80等等。现在对于中小型项目,主流都是使用支付宝支付和微信支付这两种第三方方式。

不管哪种第三方方式都有可能出现掉单的情况,出现掉单的原因可能有很多种。但有一种非常常见,就是在异步通知的时候订单校验失败(不管哪种支付方式订单校验是必须要做的一种安全校验,当然实际还需校验其他的东西,比如说appid);而之所以出现,金额校验不通过情况就是因为某些金额数字包含某些小数;如果是直接比较,那么显然会出问题。

现在举一个例子,假设使用的微信支付,支付金额为32.30;那么订单的实际支付金额是32.30,微信异步通知的金额是3230(以分为单位),如果直接比较,那么就返回false,那自然接下来更新订单状态等等一系列操作都不能执行下去了,因为校验都没通过。

var_dump(32.30*100==3230);——-显示bool(false)

按理说,我们人的数学计算,这个结果应该是true,然而机器和人还是不一样的,要知道现在的机器是基于二进制的,因此才会造成误差,具体大家可以在网上阅读相关资料。

然而如果这么来比较,又会显示不一样的结果:

var_dump(bcmul(32.30,100)==3230);—-显示bool(true)

而其中的bcmul就属于PHP数学扩展中的BC函数库,是其中用于对2个任意精度数字乘法计算的函数。

BC函数库包含了加减乘除、乘方、二次根等多种高精度计算函数,具体如下:

  1. bcadd — 2个任意精度数字的加法计算
  2. bccomp — 比较两个任意精度的数字
  3. bcdiv — 2个任意精度的数字除法计算
  4. bcmod — 对一个任意精度数字取模
  5. bcmul — 2个任意精度数字乘法计算
  6. bcpow — 任意精度数字的乘方
  7. bcpowmod — 求高精度数字乘方求模,数论里非常常用
  8. bcscale — 设置所有bc数学函数的默认小数点保留位数
  9. bcsqrt — 任意精度数字的二次方根
  10. bcsub — 2个任意精度数字的减法

以上函数具体内容可以参考PHP官方文档关于BC函数库的介绍:

http://php.net/manual/zh/ref.bc.php

 

与我们的项目经理联系
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流

转载请注明出处:利用PHP高精确度运算BC函数库解决小数计算异常问题 - 微构网络
分享: