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+APACHE实现用户论证的方法
Oct 09 PHP
PHP Mysql编程之高级技巧
Aug 27 PHP
PHP实现变色验证码实例
Jan 06 PHP
php中time()与$_SERVER[REQUEST_TIME]用法区别
Nov 19 PHP
php生成rss类用法实例
Apr 14 PHP
两种php给图片加水印的实现代码
Apr 18 PHP
如何正确配置Nginx + PHP
Jul 15 PHP
Laravel学习教程之request validation的编写
Oct 25 PHP
PHP 中 var_export、print_r、var_dump 调试中的区别
Jun 19 PHP
php中的依赖注入实例详解
Aug 14 PHP
Thinkphp 3.2框架使用Redis的方法详解
Oct 24 PHP
php实现根据身份证获取精准年龄
Feb 26 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制作新闻系统的思路
2006/10/09 PHP
用Zend Encode编写开发PHP程序
2006/10/09 PHP
php实现上传图片生成缩略图示例
2014/04/13 PHP
基于ThinkPHP+uploadify+upload+PHPExcel 无刷新导入数据
2015/09/23 PHP
PHP自带方法验证邮箱、URL、IP是否合法的函数
2016/12/08 PHP
ThinkPHP 在阿里云上的nginx.config配置实例详解
2017/10/11 PHP
PHP实现微信红包金额拆分试玩的算法示例
2018/04/07 PHP
js判断变量是否空值的代码
2008/10/26 Javascript
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
javascript实现上传图片并预览的效果实现代码
2011/04/11 Javascript
getElementByIdx_x js自定义getElementById函数
2012/01/24 Javascript
jQuery判断元素是否存在的可靠方法
2014/05/06 Javascript
js实现的在线调色板功能完整实例
2016/12/21 Javascript
微信小程序 扎金花简单实例
2017/02/21 Javascript
js实现手机发送验证码功能
2017/03/13 Javascript
Vue三种常用传值示例(父传子、子传父、非父子)
2018/07/24 Javascript
layui递归实现动态左侧菜单
2019/07/26 Javascript
javascript中undefined的本质解析
2019/07/31 Javascript
Vue获取页面元素的相对位置的方法示例
2020/02/05 Javascript
python3生成随机数实例
2014/10/20 Python
Python爬取三国演义的实现方法
2016/09/12 Python
Python读取系统文件夹内所有文件并统计数量的方法
2018/10/23 Python
python爬虫之自制英汉字典
2019/06/24 Python
Python3内置模块random随机方法小结
2019/07/13 Python
Python标准库:内置函数max(iterable, *[, key, default])说明
2020/04/25 Python
Python中and和or如何使用
2020/05/28 Python
python 5个实用的技巧
2020/09/27 Python
python 简单的调用有道翻译
2020/11/25 Python
浅谈css3中的渐进增强和优雅降级
2017/12/01 HTML / CSS
美国内衣第一品牌:Hanes(恒适)
2016/07/29 全球购物
SOKOLOV官网:俄罗斯珠宝首饰品牌
2021/01/02 全球购物
总经理检讨书
2014/09/15 职场文书
家庭困难证明
2014/10/12 职场文书
2016银行招聘自荐信
2016/01/28 职场文书
涨工资申请书应该怎么写?
2019/07/08 职场文书
vue如何使用模拟的json数据查看效果
2022/03/31 Vue.js