在商城类的项目当中,避免不了钱数的计算,也就会出现所谓的浮点数精度问题,前两天阅文的小哥哥面试我的时候就问到了这个,Mysql怎么去存钱数?PHP又该怎么处理浮点数?
在数据库去存这些精确的数值的时候,我们会使用decimal
去存储
我们使用PHP对浮点数进行加减乘除计算的时候,有时会遇到一些计算结果错误的问题,比如这样:
<?php
$num = 0.58;
var_dump(intval($num * 100));
会输出int(57)
,为什么输出57,PHP鸟哥对这个问题做了解释,感兴趣的可以看一下,地址:PHP浮点数的一个常见问题的解答 | 风雪之隅
PHP怎么去确保精确的数值呢?小哥哥告诉我PHP有个函数库,可以了解一下
BC是Binary Calculator
的缩写
BC高精确度函数库,它包含了:相加,比较,相除,相减,求余,相乘,N次方,配置默认小数点数目,求平方
还以上面的例子为准,测试一下bcmul
,2个任意精度数字的乘法计算
var_dump(bcmul('0.58', '100'));
这样就会输出string(2) "58"
,BC系列函数返回结果为字符串类型,但是结果也是准确的
对于第三个参数:scale
,用于设置结果中的小数点后的小数位数
var_dump(bcmul('1.34747474747', '35', 3));
输出string(6) "47.161"
,保留3位小数,也就是第三个参数的作用了
其他的函数可以看一下PHP的手册
bcadd — 将两个高精度数字相加
bccomp — 比较两个高精度数字,返回-1, 0, 1
bcdiv — 将两个高精度数字相除
bcmod — 求高精度数字余数
bcmul — 将两个高精度数字相乘
bcpow — 求高精度数字乘方
bcpowmod — 求高精度数字乘方求模,数论里非常常用
bcscale — 配置默认小数点的位数,相当于linux的bc中的“scale=”
bcsqrt — 求高精度数字平方根
bcsub — 将两个高精度数字相减
阅文面试的小哥哥,人也是很不错的,对于我不了解或者不熟悉的知识也给予了指导,也很感谢这个小哥哥 😆
这句话共勉吧:梦想不是浮躁,而是沉淀和积累
这个bc库好像有点问题啊 比如bcadd(0.58,100.11,0);
得到的是100,为啥不是101呢~ 不是四舍五入?
@龙笑天 四舍五入有精确度吗
@沈唁 我还是老实用round吧…
@龙笑天 你是傻子吧,精度0当然四舍五入了
PHP就这点不好,一大堆函数,常见的有上千种之多。好处就是这些底层写好的函数就不用自己再去写逻辑代码了
@西枫里博客 对啊,没用过就不清楚