浮点数乘积的取整intval,以及高精度函数bcmath的使用
线上发现个bug,浮点数乘积以后取整,得到的数不符预期。还记得上次踩过的坑是数据库类型转换的一个问题。这个也相当于类型转换了..尴尬
浮点数计算的精度一定要谨慎。
例子如下:
<?php $a = 18359.1; $b = $a * 100;// float(1835910) $c = intval($a * 100);// int(1835909) var_dump($b); var_dump($c);
究其原因,就是浮点数的二进制表示。当遇到循环的情况,就会出现这种问题。比如 18359.1 * 100在二进制运算结果后,转十进制,得到的会是1835909.99999...
这样intval()以后,便是1835909了。
知道了这样的问题,有啥更好的方案么?
可以使用bcmath扩展,高精度函数的使用。bc 全称 Binary Calculator,二进制计算器。
用法见php文档:http://php.net/manual/zh/function.bcadd.php
bcadd — 加法 bccomp — 比较 bcdiv — 相除 bcmod — 求余数 bcmul — 乘法 bcpow — 次方 bcpowmod — 先次方然后求余数 bcscale — 给所有函数设置小数位精度 bcsqrt — 求平方根 bcsub — 减法
bc库的加减乘除的返回值是string字符串类型。这点值得注意,可以设置第三个参数,小数点位数。