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分页函数
Oct 09 PHP
用PHP制作静态网站的模板框架(四)
Oct 09 PHP
php合并数组array_merge函数运算符加号与的区别
Oct 31 PHP
php文本转图片自动换行的方法
Mar 13 PHP
PHP file_get_contents设置超时处理方法
Sep 30 PHP
ThinkPHP 3.2 数据分页代码分享
Oct 14 PHP
php查找指定目录下指定大小文件的方法
Nov 28 PHP
PHP中的闭包(匿名函数)浅析
Feb 07 PHP
php继承中方法重载(覆盖)的应用场合
Feb 09 PHP
Laravel 5框架学习之Laravel入门和新建项目
Apr 07 PHP
ThinkPHP中create()方法自动验证实例
Apr 26 PHP
phpStudy2016 配置多个域名期间遇到的问题小结
Oct 19 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 判断访客是否为搜索引擎蜘蛛的函数代码
2011/07/29 PHP
php返回json数据函数实例
2014/10/09 PHP
smarty自定义函数htmlcheckboxes用法实例
2015/01/22 PHP
php去掉文件前几行的方法
2015/07/29 PHP
php中二维数组排序问题方法详解
2015/08/28 PHP
PHP简单遍历对象示例
2016/09/28 PHP
新浪刚打开页面出来的全屏广告代码
2007/04/02 Javascript
实现变速回到顶部的JavaScript代码
2011/05/09 Javascript
JS实现Enter键跳转及控件获得焦点
2013/08/12 Javascript
Jquery倒计时源码分享
2014/05/16 Javascript
For循环中分号隔开的3部分的执行顺序探讨
2014/05/27 Javascript
javascript常用方法汇总
2014/12/02 Javascript
JavaScript使用setInterval()函数实现简单轮询操作的方法
2015/02/02 Javascript
jQuery oLoader实现的加载图片和页面效果
2015/03/14 Javascript
javascript模拟php函数in_array
2015/04/27 Javascript
使用node.js对音视频文件加密的实例代码
2017/08/30 Javascript
Vue是怎么渲染template内的标签内容的
2020/06/05 Javascript
html+vue.js 实现漂亮分页功能可兼容IE
2020/11/07 Javascript
原生JavaScript实现进度条
2021/02/19 Javascript
[08:38]DOTA2-DPC中国联赛 正赛 VG vs Elephant 选手采访
2021/03/11 DOTA
python的random模块及加权随机算法的python实现方法
2017/01/04 Python
Python排序算法之选择排序定义与用法示例
2018/04/29 Python
Python学习笔记之pandas索引列、过滤、分组、求和功能示例
2019/06/03 Python
解决paramiko执行命令超时的问题
2020/04/16 Python
在echarts中图例legend和坐标系grid实现左右布局实例
2020/05/16 Python
python中加背景音乐如何操作
2020/07/19 Python
全球酒店预订网站:Hotels.com
2016/08/10 全球购物
英国汽车和货车租赁网站:Hertz英国
2016/09/02 全球购物
Carter’s OshKosh加拿大:购买婴幼儿服装和童装
2018/11/27 全球购物
新学期开学寄语
2014/01/18 职场文书
2014年圣诞节促销方案
2014/03/14 职场文书
任命书标准格式
2015/03/02 职场文书
大学军训通讯稿(2016最新版)
2015/12/21 职场文书
Java数据结构之链表相关知识总结
2021/06/18 Java/Android
Python数据结构之队列详解
2022/03/21 Python
springboot入门 之profile设置方式
2022/04/04 Java/Android