首先看一个例子:
<?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.00000000000000000000printf("%.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); // falsevar_dump(round(($c-$b),1)==round($a,1)); // true?>
2.使用高精度运算方法 
首先进行运算时,使用高精度的运算方法,这样可以保证精度不丢失。
高精度运算的方法如下: 
bcadd    将两个高精度数字相加 
bccomp   比较两个高精度数字,返回-1,0,1 
bcp    将两个高精度数字相除 
bcmod    求高精度数字余数 
bcmul    将两个高精度数字相乘 
bcpow    求高精度数字乘方 
bcpowmod 求高精度数字乘方求模 
bcscale  配置默认小数点位数,相当于Linux bc中的”scale=”  
bcsqrt   求高精度数字平方根 
bcsub    将两个高精度数字相减
例子:
<?php$a = 0.1;$b = 0.9;$c = 1; var_dump(($c-$b)==$a); // falsevar_dump(bcsub($c, $b, 1)==$a); // true?>
本文讲解了关于php 浮点数比较方法,更多相关内容请关注php中文网。
相关推荐:
php array_push 与 $arr[]=$value 之间的性能对比
以上就是关于php 浮点数比较方法 的讲解的详细内容,更多请关注php中文网其它相关文章!
                        
                        PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号