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 相关文章推荐
自己动手做一个SQL解释器
Oct 09 PHP
Windows下的PHP5.0详解
Nov 18 PHP
php中文字符截取防乱码
Mar 28 PHP
PHP初学者常见问题集合 修正版(21问答)
Mar 23 PHP
深入php数据采集的详解
Jun 02 PHP
一组PHP可逆加密解密算法实例代码
Jan 21 PHP
Drupal7连接多个数据库及常见问题解决
Mar 02 PHP
CodeIgniter实现更改view文件夹路径的方法
Jul 04 PHP
Yii分页用法实例详解
Dec 04 PHP
yii使用activeFileField控件实现上传文件与图片的方法
Dec 28 PHP
YII CLinkPager分页类扩展增加显示共多少页
Jan 29 PHP
PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】
Jun 14 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通过字符串调用函数示例
2014/03/02 PHP
举例讲解PHP面对对象编程的多态
2015/08/12 PHP
PHP实现打包zip并下载功能
2018/06/12 PHP
JavaScript 语言的递归编程
2010/05/18 Javascript
Javascript中的for in循环和hasOwnProperty结合使用
2013/06/05 Javascript
Javascript window对象详解
2014/11/12 Javascript
详解addEventListener的三个参数之useCapture
2015/03/16 Javascript
jquery仿QQ登录账号选择下拉框效果
2016/03/22 Javascript
JS输出空格的简单实现方法
2016/09/08 Javascript
angular 用拦截器统一处理http请求和响应的方法
2017/06/08 Javascript
使用vue官方提供的模板vue-cli搭建一个helloWorld案例分析
2018/01/16 Javascript
vue实现顶部菜单栏
2020/11/08 Javascript
一篇不错的Python入门教程
2007/02/08 Python
Perl中著名的Schwartzian转换问题解决实现
2015/06/02 Python
python实现的系统实用log类实例
2015/06/30 Python
深入理解python多进程编程
2016/06/12 Python
Python3下错误AttributeError: ‘dict’ object has no attribute’iteritems‘的分析与解决
2017/07/06 Python
python 通过logging写入日志到文件和控制台的实例
2018/04/28 Python
通过python的matplotlib包将Tensorflow数据进行可视化的方法
2019/01/09 Python
Python实现监控Nginx配置文件的不同并发送邮件报警功能示例
2019/02/26 Python
详解Python3 基本数据类型
2019/04/19 Python
python按比例随机切分数据的实现
2019/07/11 Python
python实现连连看辅助之图像识别延伸
2019/07/17 Python
Python Pandas 转换unix时间戳方式
2019/12/07 Python
python 使用递归实现打印一个数字的每一位示例
2020/02/27 Python
python+selenium+chromedriver实现爬虫示例代码
2020/04/10 Python
python实现简单贪吃蛇游戏
2020/09/29 Python
前端面试必备之CSS3的新特性
2017/09/05 HTML / CSS
英国知名衬衫品牌美国网站:Charles Tyrwhitt美国
2016/08/28 全球购物
英国领先的奢侈品零售商之一:CRUISE
2016/12/02 全球购物
美国购买新书和二手书网站:Better World Books
2018/10/31 全球购物
会计应聘求职信范文
2013/12/17 职场文书
县优秀教师事迹材料
2014/01/31 职场文书
学校运动会简讯
2015/07/20 职场文书
Anaconda安装pytorch及配置PyCharm 2021环境
2021/06/04 Python
MyBatis核心源码深度剖析SQL语句执行过程
2022/05/20 Java/Android