作者简介:

       姜海强:闷骚码农,互联网行业摸爬滚打数余载,先后担任中国体育直播TV主程、网信集团先锋支付架构师、奇虎360服务器端资深开发。热爱技术,喜欢分享,热衷领域:PHP/Golang语言、面向对象设计模式、Redis、Yaf、Yii2、微服务等。

视频课程

yaf+yar微服务-腾讯课堂
yaf+yar微服务-51CTO学院
CSDN学院

Github

个人主页
swoole-boot
roach
roach-orm

QQ群:

姜海强的QQ群

公众号:

360tryst公众号

bcmath

对于任意精度的数学,bcmath提供了支持用字符串表示的任意大小和精度的数字的二进制计算,最多为2147483647-1

在编译PHP时加上参数--enable-bcmath即可启用改扩展,也可以在编译安装完成后,通过phpize方式安装,源码目录位于PHP的源码目录中的ext目录。

phpize安装方式可以参考http://404.360tryst.com/views/7.html#layout

1.浮点型计算问题

也许有人会说,PHP不是提供了数学运算的符号,比如说+,-,*,\等运算,为什么还要bcmath呢,下面给大家看一下例子

  1. <?php
  2. $a = 1.5 - 1.2;
  3. var_dump($a === 0.3);

上面例程会输出true吗?也许你会想这么简单的问题,肯定返回true啊,下面来看运行结果

  1. bool(false)

不要怀疑自己的眼睛,确实是false,为什么是false呢?关于浮点数计算精度的问题原因网上有很多的解析,我就不在这里做过多的解释。

遇到上面的问题,我们应该怎么去解决呢?做过微信支付的朋友可能知道,微信支付的接口人民币的单位是,人民币最小的单位也是,那么就将小数运算变成了整数运算,这样就规避了问题。

还有其他方案吗?肯定是有的,就是本文要介绍的扩展。

2.bcmath运算

从上面例程我们可以看出,浮点型数学计算是有问题的,那么bcmath扩展怎么做运算呢?

  • 常用函数
函数名称 函数功能
bcadd($left_operand, $right_operand, $scale = 0) 2个任意精度数字的加法计算
bcsub($left_operand, $right_operand, $scale = 0) 2个任意精度数字的减法
bcmul($left_operand, $right_operand, $scale = 0) 2个任意精度数字乘法计算
bcdiv($dividend, $divisor, $scale = 0) 2个任意精度的数字除法计算
bccomp($left_operand, $right_operand, $scale = 0) 比较两个任意精度的数字,如果left大返回1,相等返回0,left小返回-1

以上5个函数第三个参数的作用是设置结果中小数点后的小数位数,默认是0

  1. <?php
  2. $a = 1.5 - 1.2;
  3. var_dump(bccomp($a, '0.2', 1));
  4. var_dump(bccomp($a, '0.3', 1));
  5. var_dump(bccomp($a, '0.4', 1));

同样是以上运算,用bccomp去比较,结果何如呢?

  1. int(1)
  2. int(0)
  3. int(-1)

我们可以看到结果是符合我们预期的,当我们遇到浮点型做计算的时候,最好使用bcmath来做运算。

QQ群:

姜海强的QQ群

公众号:

360tryst公众号