电商或财务系统计算钱精度的问题
在财务系统中经常,国内最小是分,比如说一件东西0.58元,如果买一百件那应该是58元吧? 用php表示计算
<?php
var_dump(0.58*100) ;//58
?>
结果正确,但是在看一下,下面的结果,怎么就变成57了呢?
<?php
var_dump(intval(0.58*100));//57
?>
是php的bug吗?
那让我们再看一下,javascript,运行下面的代码,你会发现第一个输出怎么不是0.3?
console.log(0.1 + 0.2);
console.log(0.1 + 0.2 == 0.3);
因此php 表示这个锅,我不背,搞懂这些就要了解浮点数在计算机中表示的方法.
浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).
0.58的二进制表示基本上(52位)是: 0010100011110101110000101000111101011100001010001111, 如果只是通过这52位计算的话是 0.58 -> 0.57999999999999996,至于0.58 * 100的具体浮点数乘法, 我们不考虑那么细,我们就模糊的以心算来看… 0.58 * 100 = 57.999999999
那你intval一下, 自然就是57了….
因此浮点数的计算和比较是有误差的.
在php中如何来解决这个问题呢?可以有两种方法
方法1:PHP 为任意精度数学计算提供了二进制计算器(Binary Calculator),它支持任意大小和精度的数字,以字符串(非浮点数)形式描述
bcadd — 加法
bccomp — 比较
bcdiv — 相除
bcmod — 求余数
bcmul — 乘法
bcpow — 次方
bcpowmod — 先次方然后求余数
bcscale — 给所有函数设置小数位精度
bcsqrt — 求平方根
bcsub — 减法
方法2: 如果需要转成整形转换成多少分钱取整,最后第三个100是换回成多少元显示
还是上面的 就是 round(0.58*100)*100/100;
那前面挖的坑,在javascript也有对应的函数,Math.round,可以通过Math.round(0.58*100),将小数转换成整数,最后再除100,转换成元显示。也就是说,单位元仅用于显示,不做计算。
相关文章
- 随时更新———个人喜欢的关于模式识别、机器学习、推荐系统、图像特征、深度学习、数值计算、目标跟踪等方面个人主页及博客
- Google Earth Engine(GEE)——以MODIS影像为例计算植被指数批量统计北京市各区逐年EVI/NDVI均值、标准差、方差统计分析和CSV下载
- Google Earth Engine(GEE)——NPP(每 8 天的 NPP)的计算一文全解析内含NPP和GPP计算公式(四川省为例)
- 基于排队理论的云计算模型的MATLAB仿真
- 【MATLAB教程案例87】使用Euler法计算lorenz混沌系统
- 一种新的计算OFDM系统误码率
- 基于systemgenerator的根号计算
- 一文看懂推荐系统:召回02:Swing 模型,和itemCF很相似,区别在于计算相似度的方法不一样
- 《OpenACC并行编程实战》—— 3.3 计算构件kernels
- 云计算的三种服务模式
- 基于Spark图计算的社会网络分析系统【100010313】
- 如何计算时间复杂度
- 《云计算:概念、技术与架构》一3.3 目标与收益
- 《Storm分布式实时计算模式》——2.5 自动化集群配置
- 【毕业设计_课程设计】基于Spark图计算的社会网络分析系统的设计和实现-顶点分析(源码+论文)
- 随时更新———个人喜欢的关于模式识别、机器学习、推荐系统、图像特征、深度学习、数值计算、目标跟踪等方面个人主页及博客
- 信息技术不断进步 监控系统云计算升级
- Red Hat认为业务转型的成熟程度已经超越了云计算
- 云计算加速中国企业发展 听华三通信这样解读
- Certigrad——随机计算图优化系统
- 计算坡度与坡向
- 计算山体阴影
- 滴滴CEO程维:在大数据、人工智能、云计算领持续投入
- 戴尔发布面向制造、生命科学和研究的高性能计算系统
- C#计算一段程序运行时间的三种方法
- 当CPU成为计算单元之一
- 甲骨文全球同时裁员:断臂求生激战云计算