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 smarty函数扩展
Mar 15 PHP
PHP缓存技术的使用说明
Aug 06 PHP
对淘宝URL中ID提取的PHP代码
Sep 01 PHP
jQuery+PHP+ajax实现微博加载更多内容列表功能
Jun 27 PHP
PHP输入流php://input实例讲解
Dec 22 PHP
CI(Codeigniter)的Setting增强配置类实例
Jan 06 PHP
PHP判断FORM表单或URL参数来的数据是否为整数的方法
Mar 25 PHP
php中foreach结合curl实现多线程的方法分析
Sep 22 PHP
PHP中overload与override的区别
Feb 13 PHP
PHP基于mcript扩展实现对称加密功能示例
Feb 21 PHP
php 使用mpdf实现指定字段配置字体样式的方法
Jul 29 PHP
php将xml转化对象的实例详解
Nov 17 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
我的论坛源代码(六)
2006/10/09 PHP
从Web查询数据库之PHP与MySQL篇
2009/09/25 PHP
PHP5中使用PDO连接数据库的方法
2010/08/01 PHP
PHP将XML转数组过程详解
2013/11/13 PHP
php从数据库中读取特定的行(实例)
2017/06/02 PHP
Laravel 类和接口注入相关的代码
2019/10/15 PHP
javascript 可以拖动的DIV(二)
2009/06/26 Javascript
将jQuery应用于login页面的问题及解决
2009/10/17 Javascript
JS实现div居中示例
2014/04/17 Javascript
firefox浏览器用jquery.uploadify插件上传时报HTTP 302错误
2015/03/01 Javascript
JS实现双击屏幕滚动效果代码
2015/10/28 Javascript
实例分析vue循环列表动态数据的处理方法
2018/09/28 Javascript
使用jQuery动态设置单选框的选中效果
2018/12/06 jQuery
使用 Element UI Table 的 slot-scope方法
2019/10/10 Javascript
vue 动态组件(component :is) 和 dom元素限制(is)用法说明
2020/09/04 Javascript
python生成excel的实例代码
2017/11/08 Python
python实现excel读写数据
2021/03/02 Python
浅谈Pandas:Series和DataFrame间的算术元素
2018/12/22 Python
使用Python检测文章抄袭及去重算法原理解析
2019/06/14 Python
Python小程序之在图片上加入数字的代码
2019/11/26 Python
Python定义函数实现累计求和操作
2020/05/03 Python
python打开音乐文件的实例方法
2020/07/21 Python
scrapy结合selenium解析动态页面的实现
2020/09/28 Python
python request 模块详细介绍
2020/11/10 Python
Django中的DateTimeField和DateField实现
2021/02/24 Python
美国婚礼装饰和活动用品批发供应商:Event Decor Direct
2018/10/12 全球购物
请说出你所知道的线程同步的方法
2013/04/19 面试题
毕业班联欢会主持词
2014/03/27 职场文书
大学生就业求职信
2014/06/12 职场文书
松材线虫病防治方案
2014/06/15 职场文书
文员求职信
2014/07/15 职场文书
森马旗舰店双十一营销方案
2014/09/29 职场文书
2015年乡镇扶贫工作总结
2015/04/08 职场文书
2015年市场营销工作总结
2015/07/23 职场文书
工伤调解协议书
2016/03/21 职场文书
Redis6.0搭建集群Redis-cluster的方法
2021/05/08 Redis