php浮点型比较踩到的坑

2018-12-03  本文已影响0人  胡乱唱歌ing

因为最近要做一个图表,x轴的叠加为0.1,但是在进行浮点类型比较时出现一个头疼的问题,废话不说请看以下案例

for($i=0.1;$i<=1.0;$i+=0.1)
{
   if($i == 1.0)
   {
       echo "ok"; 
   }else 
   {
       echo $i."<br/>";
   }
}

以上代码没有输出OK的,echo $i;能正确输出 0.1 - 1;
于是我把上面的代码改成这样子

$c = 0;
for($i=0.1;$i<=1.0;$i+=0.1)
{
    $c = $i;
}
var_dump($c);//float(1)
var_dump(1.0);//float(1)
var_dump($c == 1.0);//bool(false)
printf("%.20f",$c); //0.99999999999999988898
echo "\n";
printf("%.20f",1.0); //1.00000000000000000000
echo "\n";

问题显而易见了,c变量并不是等于1.0而是0.99...小数
参考:http://www.laruence.com/2013/03/26/2884.html
有限的小数在二进制中可能是无限长的小数

for($i=0.1;$i<=1.0;$i+=0.1)
{
   
   //使用bccomp函数对浮点数进行比较
    if(bccomp($c,1.0) == 0)
    {
        echo "ok"; 
    }else 
    {
        echo $i."<br/>";
    }
}

果然,转成string类型在进行比较就可以了。。
其实PHP也提供了高精度数字的运算函数
bcadd — 将两个高精度数字相加
bccomp — 比较两个高精度数字,返回-1, 0, 1
bcdiv — 将两个高精度数字相除
bcmod — 求高精度数字余数
bcmul — 将两个高精度数字相乘
bcpow — 求高精度数字乘方
bcpowmod — 求高精度数字乘方求模,数论里非常常用
bcscale — 配置默认小数点位数,相当于就是Linux bc中的”scale=”
bcsqrt — 求高精度数字平方根
bcsub — 将两个高精度数字相减
http://php.net/manual/zh/function.bccomp.php

上一篇 下一篇

猜你喜欢

热点阅读