两个变量何时被认为是相等的?

时间:2011-10-27 21:24:01

标签: php

我有一些变量存储在一个对象中(为了排除故障)我正在提取并转换成浮点数进行比较。出于某种原因,一些PHP并没有将某些属性视为相等(当它们出现在所有外观中时),无论是否直接比较属性,提取它们或比较它们的浮点值:

$lat1 = $coordinates1->latitude; $lat2 = $coordinates2->latitude;
$lon1 = $coordinates1->longitude; $lon2 = $coordinates2->longitude;
if (floatval($lat1) == floatval($lat2)) {
    $myLog->debug("[".floatval($lat1)."] == [".floatval($lat2)."]");
} else {
    $myLog->debug("[".floatval($lat1)."] != [".floatval($lat2)."]");
}
if (floatval($lon1) == floatval($lon2)) {
    $myLog->debug("[".floatval($lon1)."] == [".floatval($lon2)."]");
} else {
    $myLog->debug("[".floatval($lon1)."] != [".floatval($lon2)."]");
}

对于两组不同的值,调试日志中的结果如下:

[42.398264] != [42.442251]
[-83.316297] != [-83.33669]
[42.398264] == [42.398264]
[-83.316297] != [-83.316297]

我错过了什么?

3 个答案:

答案 0 :(得分:3)

浮点数的十进制字符串表示形式并不完全等于浮点数的真实值。两个浮点数可能有不同的值,但它们的字符串表示形式与某些有效数字相同。

答案 1 :(得分:2)

不要比较浮点数是否相等。它永远不会按你想要的方式工作。

它在计算机上失败的原因与十进制失败的原因相同。如果你代表1/3是.33333那么3 *(1/3)不等于1.如果你代表2/3为.66667,那么2/3 - 1/3 - 1/3不等于零和2 *(1/3)不等于(2/3)。如果您将2/3表示为.66666,则2/3 + 1/3不等于1.

因此,比较花车的平等性会以各种可怕和不可预测的方式失败。

血腥细节在What Every Computer Scientist Should Know About Floating-Point Arithmetic中解释。

答案 2 :(得分:0)

我的第一个猜测是输出函数(debug)将值四舍五入,内部存储的值更高......

我实际上有一些代码(Python而不是PHP)也处理lat / lons,我最终做的事情(这远非新的,适用于很多情况)是定义一个小数字,比如1e -5(1/100000)并通过取coords差的绝对值来测试相等性。如果它小于这个小数字,则认为它们是平等的。

类似

constant TINY = 1e-6

if ( abs(lat1 - lat2) < TINY )
    // they are equal
else
    // they are not equal

HTH

编辑 - DEF阅读大卫链接到你的文字......