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
PHP禁止页面缓存的代码
Oct 23 PHP
PHP根据IP判断地区名信息的示例代码
Mar 03 PHP
php中执行系统命令的方法
Mar 21 PHP
android上传图片到PHP的过程详解
Aug 03 PHP
PHP信号量基本用法实例详解
Feb 12 PHP
php 指定范围内多个随机数代码实例
Jul 18 PHP
PHP 输出缓冲控制(Output Control)详解
Aug 25 PHP
PHP实现查询手机归属地的方法详解
Apr 28 PHP
Laravel中任务调度console使用方法小结
May 07 PHP
PHP实现的DES加密解密类定义与用法示例
Nov 02 PHP
PHP文件后缀不强制为.php方法
Mar 31 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处理图片变得简单 基于gb库的图片处理类附实例代码下载
2011/05/17 PHP
PHP中empty,isset,is_null用法和区别
2017/02/19 PHP
Gambit vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
window.location.reload()方法刷新页面弹出要再次显示该网页对话框
2013/04/24 Javascript
JQuery中使用Ajax赋值给全局变量失败异常的解决方法
2014/08/18 Javascript
js实现点击按钮后给Div图层设置随机背景颜色的方法
2015/05/06 Javascript
通过Jquery.cookie.js实现展示浏览网页的历史记录超管用
2015/10/23 Javascript
实例代码详解jquery.slides.js
2015/11/16 Javascript
基于jquery实现鼠标左右拖动滑块滑动附源码下载
2015/12/23 Javascript
Bootstrap实现input控件失去焦点时验证
2016/08/04 Javascript
利用JavaScript阻止表单提交的两种方法
2016/08/11 Javascript
Vue.js 表单校验插件
2016/08/14 Javascript
js实现数组去重方法及效率?Ρ? target=
2017/02/14 Javascript
jQuery插件FusionCharts绘制的2D帕累托图效果示例【附demo源码】
2017/03/28 jQuery
vue货币过滤器的实现方法
2017/04/01 Javascript
js图片加载效果实例代码(延迟加载+瀑布流加载)
2017/05/12 Javascript
jQuery实现文字超过1行、2行或规定的行数时自动加省略号的方法
2018/03/28 jQuery
详解vue中axios请求的封装
2019/04/08 Javascript
javascript实现简单打字游戏
2019/10/29 Javascript
[15:46]教你分分钟做大人——沙王
2015/03/11 DOTA
python批量创建指定名称的文件夹
2019/03/21 Python
python+selenium实现简历自动刷新的示例代码
2019/05/20 Python
Python利用matplotlib做图中图及次坐标轴的实例
2019/07/08 Python
django使用admin站点上传图片的实例
2019/07/28 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
spyder 在控制台(console)执行python文件,debug python程序方式
2020/04/20 Python
Python内置函数locals和globals对比
2020/04/28 Python
Python爬虫后获取重定向url的两种方法
2021/01/19 Python
6种非常炫酷的CSS3按钮边框动画特效
2016/03/16 HTML / CSS
HTML5 微格式和相关的属性名称
2010/02/10 HTML / CSS
Html5新增标签有哪些
2017/04/13 HTML / CSS
中专生的个人自我评价
2013/12/11 职场文书
工程售后服务承诺书
2014/05/21 职场文书
2015年五四青年节活动总结
2015/02/10 职场文书
详细分析PHP7与PHP5区别
2021/06/26 PHP
python中的3种定义类方法
2021/11/27 Python