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 array_filter除去数组中的空字符元素
Jun 21 PHP
基于PHP Web开发MVC框架的Smarty使用说明
Apr 19 PHP
PHP设计模式之责任链模式的深入解析
Jun 13 PHP
解析PHP生成静态html文件的三种方法
Jun 18 PHP
php三元运算符知识汇总
Jul 02 PHP
PHP常用工具类大全附全部代码下载
Dec 07 PHP
php制作简单模版引擎
Apr 07 PHP
PHP使用mysqli操作MySQL数据库的简单方法
Feb 04 PHP
php封装单文件上传到数据库(路径)
Oct 15 PHP
基于 Swoole 的微信扫码登录功能实现代码
Jan 15 PHP
Laravel框架分页实现方法分析
Jun 12 PHP
windows系统php环境安装swoole具体步骤
Mar 04 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
全国FM电台频率大全 - 18 湖南省
2020/03/11 无线电
Php部分常见问题总结
2006/10/09 PHP
PHP5中Cookie与 Session使用详解
2013/04/30 PHP
解析php中session的实现原理以及大网站应用应注意的问题
2013/06/17 PHP
php根据isbn书号查询amazon网站上的图书信息的示例
2014/02/13 PHP
PHP 实现公历日期与农历日期的互转换
2017/09/13 PHP
tp5框架无刷新分页实现方法分析
2019/09/26 PHP
从sohu弄下来的flash中展示图片的代码
2007/04/27 Javascript
通过JS自动隐藏手机浏览器的地址栏实现原理与代码
2013/01/02 Javascript
jquery prop的使用介绍及与attr的区别
2013/12/19 Javascript
setInterval与clearInterval的使用示例代码
2014/01/28 Javascript
js判断当前浏览器类型,判断IE浏览器方法
2014/06/02 Javascript
React-Native左右联动List的示例代码
2017/09/21 Javascript
Angular学习教程之RouterLink花式跳转
2018/05/03 Javascript
JS面向对象的程序设计相关知识小结
2018/05/26 Javascript
基于vue和websocket的多人在线聊天室
2020/02/01 Javascript
Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载操作
2020/08/31 Javascript
electron踩坑之dialog中的callback解决
2020/10/06 Javascript
[01:01:43]EG vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
python 读取文件并替换字段的实例
2018/07/12 Python
python scp 批量同步文件的实现方法
2019/01/03 Python
Flask框架工厂函数用法实例分析
2019/05/25 Python
使用canvas绘制超炫时钟
2014/12/17 HTML / CSS
HTML5 Canvas中使用用路径描画圆弧
2015/01/01 HTML / CSS
Happy Plugs官网:瑞典无线耳机品牌
2020/07/16 全球购物
提高EJB性能都有哪些技巧
2012/03/25 面试题
关于青春的演讲稿三分钟
2014/08/22 职场文书
党员个人对照检查材料思想汇报
2014/09/16 职场文书
基层党员干部四风问题整改方向和措施
2014/09/25 职场文书
庆六一宣传标语
2014/10/08 职场文书
2014年团支书工作总结
2014/11/14 职场文书
考试作弊检讨书
2015/01/27 职场文书
音乐教师个人总结
2015/02/06 职场文书
新郎父母婚礼致辞
2015/07/27 职场文书
假如给我三天光明:舟逆水而行,人遇挫而达 
2019/10/29 职场文书
SpringBoot2 参数管理实践之入参出参与校验的方式
2021/06/16 Java/Android