【问题标题】:Wrong PHP string equality错误的 PHP 字符串相等
【发布时间】:2014-05-07 16:48:38
【问题描述】:

由于某种原因,PHP 决定如果:

$a = "3.14159265358979326666666666"

$b = "3.14159265358979323846264338"

$a == $b 为真。

为什么会这样,我该如何解决?

它破坏了我的代码。

【问题讨论】:

    标签: php string equality digits


    【解决方案1】:

    你可以在相等测试中使用===

    $a = "3.14159265358979326666666666";
    $b = "3.14159265358979323846264338";
    
    if($a===$b)
    {
        echo "ok";
    }
    else
    {
        echo "nope";
    }
    

    此代码将回显nope

    ==比较是松散比较,两个字符串都会被转换成数字,不会马上比较。

    使用=== 将执行字符串比较,无需类型转换,并会为您提供想要的结果。

    您可以在PHP手册中找到更多解释:

    【讨论】:

    【解决方案2】:

    阅读PHP: Comparison Operators

    如果您将数字与字符串进行比较,或者比较涉及 数字字符串,然后将每个字符串转换为数字,然后 数值进行比较。这些规则也适用于交换机 陈述。比较时不发生类型转换 是 === 或 !== 因为这涉及比较类型以及 价值。

    其他人推荐了 BC Math,但如果你在做浮点比较,比较数字的传统方法是看它们是否相同到合理的错误级别

    $epsilon = 1.0e-10;
    if (abs($a - $b) < $epsilon) then {
        // they're the same for all practical purposes
    }
    

    【讨论】:

      【解决方案3】:

      尝试改用$a === $b;你不应该使用== 进行字符串比较。

      【讨论】:

        【解决方案4】:

        问题

        PHP 将字符串(如果可能)转换为数字 (source)。浮点数的精度有限 (source)。所以 $a == $b 因为舍入错误。

        修复

        使用===!==

        试试看

        <?php
        
        $a = "3.14159265358979326666666666";
        $b = "3.14159265358979323846264338";
        
        if ($a == $b) {
            echo "'$a' and '$b' are equal with ==.<br/>";
        } else {
            echo "'$a' and '$b' are NOT equal with ==.<br/>";
        }
        
        if ($a === $b) {
            echo "'$a' and '$b' are equal with ===.<br/>";
        } else {
            echo "'$a' and '$b' are NOT equal with ===.<br/>";
        }
        ?>
        

        结果

        '3.14159265358979326666666666' and '3.14159265358979323846264338' are equal with ==.
        '3.14159265358979326666666666' and '3.14159265358979323846264338' are NOT equal with ===.
        

        注意

        当你想做高精度数学时,你应该看看BC Math

        【讨论】:

          【解决方案5】:

          你不应该像那样比较浮点变量。

          试试这个:

          bccomp($a, $b, 26)
          

          【讨论】:

          • 非常感谢大家。
          • Re “试试这个”:或许可以解释一下?例如,神奇的数字“26”应该做什么?为什么不是 25 或 27?如果不看文档,我希望它应该是 15、16 或 17,对应于8-byte IEEE floats。请通过editing (changing) your answer 回复,而不是在 cmets 中(without "Edit:"、"Update:" 或类似的 - 答案应该看起来像是今天写的)。
          猜你喜欢
          • 2020-11-05
          • 2021-12-13
          • 1970-01-01
          • 2015-12-22
          • 2015-09-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-10
          相关资源
          最近更新 更多