PHP中浮点数计算比较及取整不准确的解决方法


Posted in PHP onJanuary 09, 2015

浮点数计算结果比较
一则浮点数计算例子如下:

$a = 0.2+0.7;

$b = 0.9;

var_dump($a == $b);

打印出的结果是:bool(false)。也就是说在这里 0.2+0.7 的计算结果与 0.9 并不相等,这显然是有违我们的常识的。

对此问题,PHP官方手册曾又说明:显然简单的十进制分数如 0.2 不能在不丢失一点点精度的情况下转换为内部二进制的格式。这和一个事实有关,那就是不可能精确的用有限位数表达某些十进制分数。例如,十进制的 1/3 变成了 0.3333333...。

我们将上面的变量用双精度格式打印出来:

$a = 0.2+0.7;

$b = 0.9;

printf("%0.20f", $a);

echo '<br />';

printf("%0.20f", $b);

输出结果如下:

0.89999999999999991118

0.90000000000000002220

显然在这里,实际上作为浮点型数据,其精度已经损失了一部分,达不到完全精确。所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。需要说明的是,这不是PHP的问题,而是计算机内部处理浮点数的问题!在 C、JAVA 等语言中也会遇到同样的问题。

所以要比较两个浮点数,需要将其控制在我们需要的精度范围内再行比较,因此使用 bcadd() 函数来对浮点数想加并进行精度转换(为字符串):

var_dump(bcadd(0.2,0.7,1) == 0.9); // 输出:bool(true)

浮点数取整

在《PHP 取整函数 ceil 与 floor》一文中,曾有例子:

<?php

echo ceil(2.1/0.7);    // 输出:4

?>

经过上面对浮点数计算的探讨,知道这是浮点数计算结果不完全精确造成的:

<?php

printf("%0.20f", (2.1/0.7));    // 输出:3.00000000000000044409

?>

经过上面对浮点数计算的探讨,知道这是浮点数计算结果不完全精确造成的,因此使用 round() 函数处理一下即可:

<?php

echo ceil( round((2.1/0.7),1) );

?>

虽然 round() 函数是按照指定的精度进行四舍五入,但保留小数点后一位,对我们的取整结果是没影响的。

PHP 相关文章推荐
从Web查询数据库之PHP与MySQL篇
Sep 25 PHP
php读取html并截取字符串的简单代码
Nov 30 PHP
php cout&amp;lt;&amp;lt;的一点看法
Jan 24 PHP
PHP is_subclass_of函数的一个BUG和解决方法
Jun 01 PHP
php隐藏IP地址后两位显示为星号的方法
Nov 21 PHP
PHP制作百度词典查词采集器
Jan 29 PHP
PHP输入输出流学习笔记
May 12 PHP
帝国cms目录结构分享
Jul 06 PHP
PHP获取文件扩展名的方法实例总结
Jun 10 PHP
Yii2.0多文件上传实例说明
Jul 24 PHP
PHP实现动态删除XML数据的方法示例
Mar 30 PHP
asp函数split()对应php函数explode()
Feb 27 PHP
php模拟登陆的实现方法分析
Jan 09 #PHP
php获取四位字母和数字的随机数的实现方法
Jan 09 #PHP
php实现读取手机客户端浏览器的类
Jan 09 #PHP
ucenter通信原理分析
Jan 09 #PHP
PHP上传文件时自动分配路径的方法
Jan 09 #PHP
PHP中new static() 和 new self() 的区别介绍
Jan 09 #PHP
PHP中的替代语法介绍
Jan 09 #PHP
You might like
重置版宣传动画
2020/04/09 魔兽争霸
实例(Smarty+FCKeditor新闻系统)
2007/01/02 PHP
php URL验证正则表达式
2011/07/19 PHP
smarty模板数学运算示例
2016/12/11 PHP
Laravel中日期时间处理包Carbon的简单使用
2017/09/21 PHP
javascript 表单规则集合对象
2009/07/21 Javascript
jquery调用asp.net 页面后台的实现代码
2011/04/27 Javascript
js 有框架页面跳转(target)三种情况下的应用
2013/04/09 Javascript
使用js实现关闭js弹出层的窗口
2014/02/10 Javascript
javascript中的正则表达式使用详解
2015/08/30 Javascript
jquery 表单验证之通过 class验证表单不为空
2015/11/02 Javascript
Document.body.scrollTop的值总为零的快速解决办法
2016/06/09 Javascript
Angular 理解module和injector,即依赖注入
2016/09/07 Javascript
用iframe实现不刷新整个页面上传图片的实例
2016/11/18 Javascript
Angular中ng-options下拉数据默认值的设定方法
2017/06/21 Javascript
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
2017/12/26 Javascript
浅谈Vue2.0中v-for迭代语法的变化(key、index)
2018/03/06 Javascript
微信小程序实现通过js操作wxml的wxss属性示例
2018/12/06 Javascript
详解elementui之el-image-viewer(图片查看器)
2019/08/30 Javascript
vscode 使用Prettier插件格式化配置使用代码详解
2020/08/10 Javascript
React实现todolist功能
2020/12/28 Javascript
[55:44]完美世界DOTA2联赛决赛 FTD vs Phoenix 第二场 11.08
2020/11/11 DOTA
python 画出使用分类器得到的决策边界
2019/08/21 Python
Python3 获取文件属性的方式(时间、大小等)
2020/03/12 Python
TensorFlow2.1.0最新版本安装详细教程
2020/04/08 Python
python中count函数知识点浅析
2020/12/17 Python
html5生成柱状图(条形图)效果的实例代码
2016/03/25 HTML / CSS
加拿大在线隐形眼镜专家:PerfectLens.ca
2016/11/19 全球购物
农药学硕士毕业生自荐信
2013/09/25 职场文书
工程地质勘察专业大学生求职信
2013/10/13 职场文书
庆元旦广播稿
2014/02/10 职场文书
巾帼标兵事迹材料
2014/12/26 职场文书
实习单位意见
2015/06/04 职场文书
巴黎圣母院观后感
2015/06/10 职场文书
团支部组织委员竞选稿
2015/11/21 职场文书
七年级作文之《我和我的祖国》观后感作文
2019/10/18 职场文书