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 相关文章推荐
分页显示Oracle数据库记录的类之一
Oct 09 PHP
全文搜索和替换
Oct 09 PHP
PHP 反射机制实现动态代理的代码
Oct 22 PHP
关于php curl获取301或302转向的网址问题的解决方法
Jun 02 PHP
mysql,mysqli,PDO的各自不同介绍
Sep 19 PHP
解析PHPExcel使用的常用说明以及把PHPExcel整合进CI框架的介绍
Jun 24 PHP
php模拟ping命令(php exec函数的使用方法)
Oct 25 PHP
PHP中的reflection反射机制测试例子
Aug 05 PHP
php实现的css文件背景图片下载器代码
Nov 11 PHP
Zend Framework教程之Zend_Layout布局助手详解
Mar 04 PHP
PHP实现留言板功能的详细代码
Mar 25 PHP
实现laravel 插入操作日志到数据库的方法
Oct 11 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
模拟flock实现文件锁定
2007/02/14 PHP
php 生成饼图 三维饼图
2009/09/28 PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
2012/08/31 PHP
国外十大最流行的PHP框架排名
2013/07/04 PHP
thinkphp5使用无限极分类
2019/02/18 PHP
js倒计时小程序
2013/11/05 Javascript
JavaScript bold方法入门实例(把指定文字显示为粗体)
2014/10/17 Javascript
js实现带关闭按钮始终显示在网页最底部工具条的方法
2015/03/02 Javascript
js+html5实现canvas绘制镂空字体文本的方法
2015/06/05 Javascript
基于Jquery实现表单验证
2020/07/20 Javascript
jquery自定义插件——window的实现【示例代码】
2016/05/06 Javascript
js实现类bootstrap模态框动画
2017/02/07 Javascript
JS实现页面打印(整体、局部)
2017/08/18 Javascript
微信小程序实现tab页面切换功能
2018/07/13 Javascript
4个顶级JavaScript高级文本编辑器
2018/10/10 Javascript
详解vue使用$http服务端收不到参数
2019/04/19 Javascript
Vue组件跨层级获取组件操作
2020/07/27 Javascript
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
2021/01/08 Vue.js
[02:40]DOTA2超级联赛专访430 从小就爱玩对抗性游戏
2013/06/18 DOTA
python获取一组数据里最大值max函数用法实例
2015/05/26 Python
tensorflow: variable的值与variable.read_value()的值区别详解
2018/07/30 Python
Python2与Python3的区别实例总结
2019/04/17 Python
Python一行代码实现快速排序的方法
2019/04/30 Python
如何使用pyinstaller打包32位的exe程序
2019/05/26 Python
python设计微型小说网站(基于Django+Bootstrap框架)
2019/07/08 Python
PyQt5通信机制 信号与槽详解
2019/08/07 Python
解析python实现Lasso回归
2019/09/11 Python
Python实现socket非阻塞通讯功能示例
2019/11/06 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
2020/11/02 Python
用OpenCV进行年龄和性别检测的实现示例
2021/01/29 Python
会计岗位职责
2013/11/08 职场文书
2014年向国旗敬礼活动总结
2014/09/27 职场文书
2014年信访维稳工作总结
2014/12/08 职场文书
教师个人考察材料
2014/12/16 职场文书
公司门卫岗位职责
2015/04/13 职场文书
肖申克救赎观后感
2015/06/02 职场文书