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 相关文章推荐
动态新闻发布的实现及其技巧
Oct 09 PHP
使用ThinkPHP自带的Http类下载远程图片到本地的实现代码
Aug 02 PHP
php获取本周开始日期和结束日期的方法
Mar 09 PHP
PHP实现删除字符串中任何字符的函数
Aug 11 PHP
一段实用的php验证码函数
May 19 PHP
CI框架中类的自动加载问题分析
Nov 21 PHP
php in_array() 检查数组中是否存在某个值详解
Nov 23 PHP
PHP curl 或 file_get_contents 获取需要授权页面的方法
May 05 PHP
PHP高效获取远程图片尺寸和大小的实现方法
Oct 20 PHP
php7函数,声明,返回值等新特性介绍
May 25 PHP
Laravel5框架添加自定义辅助函数的方法
Aug 01 PHP
PHP格式化显示时间date()函数代码
Oct 03 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 xfocus防注入资料
2008/04/27 PHP
Yii框架表单模型和验证用法
2016/05/20 PHP
Yii 2.0如何使用页面缓存方法示例
2017/05/23 PHP
php数据序列化测试实例详解
2017/08/12 PHP
Aster vs KG BO3 第二场2.19
2021/03/10 DOTA
JavaScript 函数式编程的原理
2009/10/16 Javascript
jQuery)扩展jQuery系列之一 模拟alert,confirm(一)
2010/12/04 Javascript
页面回到顶部的三种实现(锚标记,js)
2012/10/01 Javascript
nodejs npm包管理的配置方法及常用命令介绍
2014/06/05 NodeJs
js检验密码强度(低中高)附图
2014/06/05 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(二)之数据支持json字符串、list集合
2016/08/11 Javascript
jQuery布局组件EasyUI Layout使用方法详解
2017/02/28 Javascript
最适应的vue.js的form提交涉及多种插件【推荐】
2018/08/27 Javascript
angular6开发steps步骤条组件
2019/07/04 Javascript
浅谈JS中几种轻松处理'this'指向方式
2019/09/16 Javascript
Vue插件之滑动验证码用法详解
2020/04/05 Javascript
JS原型对象操作实例分析
2020/06/06 Javascript
JavaScript多种图形实现代码实例
2020/06/28 Javascript
vue 项目@change多个参数传值多个事件的操作
2021/01/29 Vue.js
[01:03:22]LGD vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
Python实现FTP上传文件或文件夹实例(递归)
2017/01/16 Python
Python的mysql数据库的更新如何实现
2017/07/31 Python
Pytorch 高效使用GPU的操作
2020/06/27 Python
Python list和str互转的实现示例
2020/11/16 Python
Django与AJAX实现网页动态数据显示的示例代码
2021/02/24 Python
一款超酷的js+css3实现的3D标签云特效兼容ie7/8/9
2013/11/18 HTML / CSS
HTML中fieldset标签概述及使用方法
2013/02/01 HTML / CSS
荷兰浴室和卫浴网上商店:Badkamerxxl.nl
2020/10/06 全球购物
敬老文明号事迹材料
2014/01/16 职场文书
高中生期末评语大全
2014/01/28 职场文书
2014社区三八妇女节活动方案
2014/03/30 职场文书
社区服务活动总结
2014/05/07 职场文书
爱护公共设施的标语
2014/06/24 职场文书
教师个人培训总结
2015/02/11 职场文书
2015年幼儿园大班工作总结
2015/04/25 职场文书
边城读书笔记
2015/06/29 职场文书