Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/241.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 两个变量何时被认为相等?_Php - Fatal编程技术网

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

Php 两个变量何时被认为相等?,php,Php,我在一个对象中存储了一些变量(为了排除故障),我正在提取这些变量并将其转换为浮点数进行比较。出于某种原因,无论我是否直接比较属性、提取属性或比较它们的浮点值,一些PHP都不认为某些属性是相等的(当它们看起来都相等时): $lat1 = $coordinates1->latitude; $lat2 = $coordinates2->latitude; $lon1 = $coordinates1->longitude; $lon2 = $coordinates2->longi

我在一个对象中存储了一些变量(为了排除故障),我正在提取这些变量并将其转换为浮点数进行比较。出于某种原因,无论我是否直接比较属性、提取属性或比较它们的浮点值,一些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]

我遗漏了什么?

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

它在计算机上失败的原因与它在十进制中失败的原因相同。如果表示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

因此,比较浮动是否相等将以各种可怕和不可预测的方式失败


血淋淋的细节在中解释。

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

它在计算机上失败的原因与它在十进制中失败的原因相同。如果表示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

因此,比较浮动是否相等将以各种可怕和不可预测的方式失败


血淋淋的细节在中解释。

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

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

我的第一个猜测是输出函数(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
常数极小=1e-6
如果(abs(lat1-lat2)<微小)
//他们是平等的
其他的
//他们不平等


编辑-定义读取David链接到的文本

我的第一个猜测是,输出函数(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
常数极小=1e-6
如果(abs(lat1-lat2)<微小)
//他们是平等的
其他的
//他们不平等


编辑-定义读取David链接到的文本

这很好,但是为什么.33333不能被认为等于.33333呢?我没有对这些数字执行任何数学运算,因为一个可能是
.3333333333
,另一个只是
.33333333
,两者的取整方式都不同。简单地加载它们是一种数学运算,因为它们在内存中的格式与在寄存器中的格式不同并进行了比较。最终结果可能取决于操作是否完全在浮点单元中执行,或者中间结果是否被写回内存。请参阅中的警告,其中建议您“永远不要比较浮点数是否相等”。浮点数基本上涉及舍入和近似。当您打印浮点数时,它将转换为十进制显示。它在内部是二进制的,映射不是1对1。感谢这篇文章-我会投票给你,但马克的答案更清楚&切中要害。这很好,但为什么.33333不能被认为等于.33333呢?我没有对这些数字执行任何数学运算,因为一个可能是
.3333333333
,另一个只是
.33333333
,两者的取整方式都不同。简单地加载它们是一种数学运算,因为它们在内存中的格式与在寄存器中的格式不同并进行了比较。最终结果可能取决于操作是否完全在浮点单元中执行,或者中间结果是否被写回内存。请参阅中的警告,其中建议您“永远不要比较浮点数是否相等”。浮点数基本上涉及舍入和近似。当您打印浮点数时,它将转换为十进制显示。它在内部是二进制的,映射不是1对1。谢谢你的文章-我会投票给你的,但马克的回答更清楚&切中要害。我想知道负数之间的比较失败是否值得注意?我想知道负数之间的比较失败是否值得注意?这更有意义。我将尝试将这些值转换成字符串,看看会发生什么。这更有意义。我将尝试将这些值转换成一个字符串,看看会发生什么。