php如何比较两个浮点数是否相等详解

php如何比较两个小数数是否相等详解

异常代码示例

利用php如何比较浮点数是否相等的相关内容

0.9+0.1 的相加结果与 1 进行比较

<?php
$a = 0.9;
$b = 0.1;
$total = $a + $b;
var_dump($total);
if (1 == $total) {
 echo "true";
} else {
 echo "false";
}
echo "\n";

if (1.0 == $total) {
 echo "true";
} else {
 echo "false";
}
?>

打印结果是:

float(1)
true
true

再看下面这段代码, 0.6+0.1+0.1+0.1+0.1 的相加结果与 1 进行比较

<?php
$a = 0.6;
$b = 0.1;
$c = 0.1;
$d = 0.1;
$e = 0.1;

$total = $a + $b + $c + $d + $e;
var_dump($total);

if (1 == $total) {
 echo "true";
} else {
 echo "false";
}
echo "\n";

if (1.0 == $total) {
 echo "true";
} else {
 echo "false";
}

?>

打印结果是:

float(1)
false
false

为什么这两段代码结果不一样?把两段代码里面的 $total 分别以精度20位的形式打印出来 printf("%.20f\n", $total); ,结果如下:

1.00000000000000000000
0.99999999999999988898

出现这个问题是因为浮点数计算涉及精度。

关于php里面的浮点数, 官方手册 上有相关解释

看官方手册里面关于浮点数的提示,如下图所示。里面提到 永远不要比较两个浮点数是否相等

那么有什么办法可以比较两个浮点数是否相等呢?

解决方法

方法一

<?php

$a = 0.6;
$b = 0.1;
$c = 0.1;
$d = 0.1;
$e = 0.1;
$epsilon = 0.00001;

$total = $a + $b + $c + $d + $e;

if(abs($total-1) < $epsilon) {
 echo "true";
} else {
 echo "false";
}
echo "\n";

if(abs($total-1.0) < $epsilon) {
 echo "true";
} else {
 echo "false";
}

?>

结果输出为:

true
true

方法二

<?php

$a = 0.6;
$b = 0.1;
$c = 0.1;
$d = 0.1;
$e = 0.1;

$total = $a + $b + $c + $d + $e;

if(1.0 == round($total, 5)) {
 echo "true";
} else {
 echo "false";
}
?>

结果输出为:

true

方法三

要比较两个浮点数的大小,可以用bccomp(参数1,参数2,小数位)来比较


$sum = 0.1;
$a = 0.01;
$b = 0.08;
$c = 0.01;
$sum = (float)$sum;
$s = (float)($a + $b + $c);
var_dump($sum, $s);
var_dump($sum == $s);
var_dump(bccomp($sum, $s, 2));
if (bccomp($sum, $s, 2) == 0) {
    echo '微信红包总金额正常!';
} else {
    echo '抱歉,微信红包总金额有异常!';
}
D:\wamp\www\hanshu\bijiao.php:54:float 0.1
D:\wamp\www\hanshu\bijiao.php:54:float 0.1
D:\wamp\www\hanshu\bijiao.php:55:boolean false
D:\wamp\www\hanshu\bijiao.php:56:int 0
微信红包总金额正常!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值