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 xfocus防注入资料
Apr 27 PHP
php 文件缓存函数
Oct 08 PHP
php中选择什么接口(mysql、mysqli)访问mysql
Feb 06 PHP
解析php利用正则表达式解决采集内容排版的问题
Jun 20 PHP
getJSON跨域SyntaxError问题分析
Aug 07 PHP
Laravel 5框架学习之Eloquent (laravel 的ORM)
Apr 08 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
Sep 22 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
Dec 15 PHP
MAC下通过改apache配置文件切换php多版本的方法
Apr 26 PHP
PHP简单实现合并2个数字键数组值的方法
May 30 PHP
PHP序列化和反序列化深度剖析实例讲解
Dec 29 PHP
浅谈如何提高PHP代码的质量
May 28 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
ThinkPHP模板比较标签用法详解
2014/06/30 PHP
javascript动画效果类封装代码
2007/08/28 Javascript
javascript 复杂的嵌套环境中输出单引号和双引号
2009/05/26 Javascript
JQuery 获取和设置Select选项的代码
2010/02/07 Javascript
jquery 单击li防止重复加载的实现代码
2010/12/24 Javascript
推荐20家国外的脚本下载网站
2011/04/28 Javascript
jquery实现的可隐藏重现的靠边悬浮层实例代码
2013/05/27 Javascript
nodejs简单读写excel内容的方法示例
2018/03/16 NodeJs
d3.js实现自定义多y轴折线图的示例代码
2018/05/30 Javascript
js Math数学简单使用操作示例
2020/03/13 Javascript
进一步理解Python中的函数编程
2015/04/13 Python
浅谈django中的认证与登录
2016/10/31 Python
在 Python 应用中使用 MongoDB的方法
2017/01/05 Python
python爬虫_实现校园网自动重连脚本的教程
2018/04/22 Python
python获取磁盘号下盘符步骤详解
2019/06/19 Python
解决Python中pandas读取*.csv文件出现编码问题
2019/07/12 Python
django做form表单的数据验证过程详解
2019/07/26 Python
Python的bit_length函数来二进制的位数方法
2019/08/27 Python
Python性能分析工具Profile使用实例
2019/11/19 Python
tensorflow生成多个tfrecord文件实例
2020/02/17 Python
python怎么判断素数
2020/07/01 Python
python多线程semaphore实现线程数控制的示例
2020/08/10 Python
python调用win32接口进行截图的示例
2020/11/11 Python
Traffic People官网:女式花裙、上衣和连身裤
2020/10/12 全球购物
汽车销售求职自荐信
2013/10/01 职场文书
音乐教师求职信
2014/06/28 职场文书
井冈山红色之旅感想
2014/10/07 职场文书
骨干教师事迹材料
2014/12/17 职场文书
人事聘任通知
2015/04/21 职场文书
故意伤害辩护词
2015/05/21 职场文书
2016年寒假社会实践活动心得体会
2015/10/09 职场文书
CSS实现切角+边框+投影+内容背景色渐变效果
2021/11/01 HTML / CSS
JavaScript流程控制(循环)
2021/12/06 Javascript
vue实力踩坑之push当前页无效
2022/04/10 Vue.js
MYSQL事务的隔离级别与MVCC
2022/05/25 MySQL
Windows11 Insider Preview Build 25206今日发布 更新内容汇总
2022/09/23 数码科技