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 相关文章推荐
怎么样可以把 phpinfo()屏蔽掉?
Nov 24 PHP
php不用正则采集速度探究总结
Mar 24 PHP
php去除html标记的原生函数详解
Jan 27 PHP
PHP实现图片上传并压缩
Dec 22 PHP
PHP数组的定义、初始化和数组元素的显示实现代码
Nov 05 PHP
php接口技术实例详解
Dec 07 PHP
php中简单的对称加密算法实现
Jan 05 PHP
PHP获取redis里不存在的6位随机数应用示例【设置24小时过时】
Jun 07 PHP
浅谈PHP中的面向对象OOP中的魔术方法
Jun 12 PHP
php实现和c#一致的DES加密解密实例
Jul 24 PHP
thinkPHP5框架设置404、403等http状态页面的方法
Jun 05 PHP
redis+php实现微博(三)微博列表功能详解
Sep 23 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
smtp邮件发送一例
2006/10/09 PHP
PHP 5.0 Pear安装方法
2006/12/06 PHP
Apache下禁止php文件被直接访问的解决方案
2013/04/25 PHP
php时区转换转换函数
2014/01/07 PHP
php获取中文拼音首字母类和函数分享
2014/04/24 PHP
避免Smarty与CSS语法冲突的方法
2015/03/02 PHP
调试WordPress中定时任务的相关PHP脚本示例
2015/12/10 PHP
PHP生成图像验证码的方法小结(2种方法)
2016/07/18 PHP
注意!PHP 7中不要做的10件事
2016/09/18 PHP
PHP 无限级分类
2017/05/04 PHP
js 提交和设置表单的值
2008/12/19 Javascript
一个字符串反转函数可实现字符串倒序
2014/09/15 Javascript
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
在JavaScript中处理数组之reverse()方法的使用
2015/06/09 Javascript
js实现div模拟模态对话框展现URL内容
2016/05/27 Javascript
Vue-Router实现页面正在加载特效方法示例
2017/02/12 Javascript
JavaScript创建对象的七种方式(推荐)
2017/06/26 Javascript
angularJs-$http实现百度搜索时的动态下拉框示例
2018/02/27 Javascript
详解微信小程序开发聊天室—实时聊天,支持图片预览
2019/05/20 Javascript
JS实现小星星特效
2019/12/24 Javascript
使用js获取身份证年龄的示例代码
2020/12/11 Javascript
[02:43]DOTA2英雄基础教程 圣堂刺客
2013/12/09 DOTA
python 中的列表解析和生成表达式
2011/03/10 Python
Ubuntu 14.04+Django 1.7.1+Nginx+uwsgi部署教程
2014/11/18 Python
深入理解Python中变量赋值的问题
2017/01/12 Python
Django学习笔记之Class-Based-View
2017/02/15 Python
Flask框架中request、请求钩子、上下文用法分析
2019/07/23 Python
你还在@微信官方?聊聊Python生成你想要的微信头像
2019/09/25 Python
Python 余弦相似度与皮尔逊相关系数 计算实例
2019/12/23 Python
双语教学实施方案
2014/03/23 职场文书
平面设计专业求职信
2014/08/09 职场文书
庆祝儿童节标语
2014/10/09 职场文书
高校自主招生校长推荐信
2015/03/23 职场文书
飞越疯人院观后感
2015/06/09 职场文书
会议营销主持词
2015/07/03 职场文书
婚宴来宾致辞
2015/07/28 职场文书