PHP找不到两个相等的数字相等?错误?

时间:2010-11-19 22:58:29

标签: php variables floating-point equals

  

可能重复:
  compare floats in php

我有条件:

if($x <= .3)
   echo 1;

只有当x小于.3才会回显1

如果$ x等于.3,我不会得到1。

我试过在floatval()中包装x,但没有运气

我试图回应$ x,我得到“0.3”

我试过if ($x == .3) - 没什么

如果我尝试if (.3 == .3)显然有效

任何想法?这是一个PHP错误吗?

6 个答案:

答案 0 :(得分:4)

所有关于浮点数的二进制表示:

var_dump(sprintf("%.40f", 0.3));
// string(42) "0.2999999999999999888977697537484345957637"

基本上,0.3不能在基数2中精确表示,因此在几位数之后会被截断。它基本上像基数10的1/3:你可以输入0.3,但0.33更精确,因此是0.333,0.3333等。你不能完全代表它。

答案 1 :(得分:1)

浮点值不准确。您可以检查它是否大致&lt; = 0.3这样:

if ($x <= 0.3000001) {
    echo 'yay';
}

答案 2 :(得分:1)

你去,大,红,胖:Floating Point Numbers

  

通常是简单的小数   像0.1或0.7的分数不能   转换成内部二进制文件   对手没有一点损失   精确。这可能会导致混淆   结果:例如,   通常((0.1 + 0.7)* 10)   返回7而不是预期的8,   因为内部代表会   就像7.9。

     

这是因为事实确实如此   不可能表达一些分数   用有限的十进制表示法   位数。例如,1/3英寸   十进制形式变为0.3。

     

所以永远不要相信浮点数结果   到最后一位数, 从不比较   相等的浮点数 。   如果需要更高的精度,那么   arbitrary precision math functions和   gmp功能可用。

PS:还有更多的乐趣:

INF == INF => false
INF < INF  => true
INF > INF  => true

因此,无穷大不是无穷大,无穷大小于无穷大,同时大于无穷大。如果你考虑一下,它确实有一些意义......

答案 3 :(得分:0)

嗯,我必须假设你的var $x真的不等于.3

我刚试过这个:

<?
    $var = 0.3;

    if( $var <= .3 )
    {
        echo 'yay';
    }
    else
    {
        echo 'boo';
    }
?>

并输出yay

答案 4 :(得分:0)

$ x = .4;
if($ x&lt; = .3){echo 1; }
在这里工作正常...尝试不同的价值$ x
但是......你在哪里得到$ x ??在比较之前,您可能需要“舍入”该值。

答案 5 :(得分:0)

浮点数不是100%准确。简而言之,通常通过将1 /(2 ^ n)加在一起来存储分数分量。例如,1/2 + 1/4是如何存储3/4。所以这不是一个错误,也不是一个特定的PHP问题。

但是,这应该是真的:

$x = 0.3;
if ($x == 0.3) echo "true";

因为两者都存在相同的不准确性。

但这不能保证是真的:

$x = 0.1;
$y = 0.2;
if ($x + $y == 0.3) echo "true";

解决此问题的一种简单方法是使用delta:

if (abs($a - $b) < $delta) echo "true"

其中$ delta是一个非常小的数字。

如果您需要准确性,请查看类似BCMath扩展名的内容。

如果这是为了赚钱,那么通常更容易以整分(整数)进行计算,其中$ 1.23 = 123。