php 浮点数比较方法详解
浮点数运算精度问题
看一个例子
<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($a+$b)==$c); var_dump(($c-$b)==$a); ?>
$a+$b==$c 返回true,正确
$c-$b==$a 返回false,错误
为什么会这样呢?
运算后,精度为20位时实际返回的内容如下
<?php $a = 0.1; $b = 0.9; $c = 1; printf("%.20f", $a+$b); // 1.00000000000000000000 printf("%.20f", $c-$b); // 0.09999999999999997780 ?>
$c-$b 为 0.09999999999999997780,与0.1比较返回false
出现这个问题是因为浮点数计算涉及精度,当浮点数转为二进制时有可能会造成精度丢失。
浮点数转二进制方法
整数部分采用除以2取余方法
小数部分采用乘以2取整方法
例如把数字8.5转为二进制
整数部分是8
8/2=4 8%2=0
4/2=2 4%2=0
2/2=1 2%2=0
1比2小,不需要计算下去,整数8的二进制为 1000
小数部分是0.5
0.5x2 = 1.0
因取整后小数部分为0,不需要再计算下去
小数0.5的二进制为 0.1
8.5的二进制为1000.1
计算数字0.9的二进制
0.9x2=1.8
0.8x2=1.6
0.6x2=1.2
0.2x2=0.4
0.4x2=0.8
0.8x2=1.6
…. 之后不断循环下去,当截取精度为N时,N后的数会被舍去,导致精度丢失。
上例中0.9在转为二进制时精度丢失,导致比较时出现错误。
所以永远不要相信浮点数已精确到一位,也永远不要比较两个浮点数是否相等。
正确比较浮点数的方法
1.使用round方法处理后再比较
例子
<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($c-$b)==$a); // false var_dump(round(($c-$b),1)==round($a,1)); // true ?>
2.使用高精度运算方法
进行运算时,使用高精度的运算方法,这样可以保证精度不丢失。
高精度运算的方法如下
bcadd 将两个高精度数字相加
bcp 比较两个高精度数字,返回-1,0,1
bcdiv 将两个高精度数字相除
bcmod 求高精度数字余数
bcmul 将两个高精度数字相乘
bcpow 求高精度数字乘方
bcpowmod 求高精度数字乘方求模
bcscale 配置默认小数点位数,相当于Linux bc中的”scale=”
bcsqrt 求高精度数字平方根
bcsub 将两个高精度数字相减
例子
<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($c-$b)==$a); // false var_dump(bcsub($c, $b, 1)==$a); // true ?>
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望多多支持狼蚁SEO!
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程