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 相关文章推荐
php程序效率优化的一些策略小结
Jul 17 PHP
PHP中利用substr_replace将指定两位置之间的字符替换为*号
Jan 27 PHP
php中引用符号(&amp;)的使用详解
Nov 13 PHP
PHP扩展CURL的用法详解
Jun 20 PHP
PHP直接修改表内容DataGrid功能实现代码
Sep 24 PHP
php表单提交实例讲解
Nov 12 PHP
PHP解耦的三重境界(浅谈服务容器)
Mar 13 PHP
Ubuntu彻底删除PHP7.0的方法
Jul 27 PHP
tp5(thinkPHP5框架)时间查询操作实例分析
May 29 PHP
Laravel框架实现多数据库连接操作详解
Jul 12 PHP
PHP实现简易图形计算器
Aug 28 PHP
PHP7 其他修改
Mar 09 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
浅析php变量修饰符static的使用
2013/06/28 PHP
php统计时间和内存使用情况示例分享
2014/03/13 PHP
浅析php设计模式之数据对象映射模式
2016/03/03 PHP
Laravel Memcached缓存驱动的配置与应用方法分析
2016/10/08 PHP
浅谈PHP中try{}catch{}的使用方法
2016/12/09 PHP
PHP开启目录引索+fancyindex漂亮目录浏览带搜索功能
2019/09/23 PHP
数理公式,也可以这么唯美
2021/03/10 无线电
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
2009/02/04 Javascript
javascript学习笔记(十六) 系统对话框(alert、confirm、prompt)
2012/06/20 Javascript
js中reverse函数的用法详解
2013/12/26 Javascript
jQuery实现的超酷苹果风格图标滑出菜单效果代码
2015/09/16 Javascript
jQuery控制DIV层实现由大到小,由远及近动画变化效果
2015/10/09 Javascript
js实现获取两个日期之间所有日期的方法
2016/06/17 Javascript
微信小程序 选择器(时间,日期,地区)实例详解
2016/11/16 Javascript
js+html获取系统当前时间
2017/11/10 Javascript
JS使用栈判断给定字符串是否是回文算法示例
2019/03/04 Javascript
JS实现图片幻灯片效果代码实例
2020/05/21 Javascript
python中使用sys模板和logging模块获取行号和函数名的方法
2014/04/15 Python
用pickle存储Python的原生对象方法
2017/04/28 Python
python批量修改图片后缀的方法(png到jpg)
2018/10/25 Python
如何将tensorflow训练好的模型移植到Android (MNIST手写数字识别)
2020/04/22 Python
Python 日期与时间转换的方法
2020/08/01 Python
非常震撼的纯CSS3人物行走动画
2016/02/24 HTML / CSS
【HTML5】Canvas绘制简单图片教程
2016/05/13 HTML / CSS
美国知名运动产品零售商:Foot Locker
2016/07/23 全球购物
乌克兰在线电子产品商店:MTA
2019/11/14 全球购物
室内设计专业个人的自我评价
2013/10/19 职场文书
求职毕业生自荐书
2014/02/08 职场文书
西式结婚主持词
2014/03/14 职场文书
主题团日活动总结
2014/06/25 职场文书
机票销售员态度不好检讨书
2014/09/27 职场文书
工厂清洁工岗位职责
2015/02/14 职场文书
化妆品促销活动总结
2015/05/07 职场文书
准备去美国留学,那么大学申请文书应该怎么写?
2019/08/12 职场文书
《西游记》读后感(3篇)
2019/09/20 职场文书
Node.js实现爬取网站图片的示例代码
2022/04/04 NodeJs