Являются ли все сравнения равенства PHP симметричными? - PullRequest
8 голосов
/ 21 января 2011

Всегда ли $a == $b эквивалентно $b == $a?

Я думаю, в JavaScript есть несколько странных случаев, когда это не так из-за приведения.

Я думаю ide правильно.Я задам еще один вопрос .

Ответы [ 5 ]

4 голосов
/ 21 января 2011

Короче да. $a == $b всегда будет эквивалентно $b == $a. Есть некоторые недостатки, такие как поплавки. Конечно, в любом случае вам не следует вкладывать два числа с плавающей точкой для равенства.

EDIT
Что касается поплавков: если у вас есть два поплавка и вы их сравнили, технически они должны быть одинаковыми. Однако значения с плавающей запятой, которые кажутся одинаковыми, не обязательно должны быть идентичными. Таким образом, если $a является литералом .69 и $b является результатом вычисления, они вполне могут быть разными, но оба отображают одно и то же значение. Вот почему вы никогда не должны сравнивать значения с плавающей точкой, используя ==.

Если вам нужно сравнить значения с плавающей запятой, вам действительно нужно использовать наименьшее допустимое различие в вашем конкретном случае. Примерно так будет работать для сравнения чисел с плавающей запятой (установив нашу наименьшую допустимую разницу в 0.000001):

if(abs($a-$b) < 0.000001) {
  //Same
}

PHP: abs - абсолютное значение

3 голосов
/ 21 января 2011

Единственный тип, который я мог видеть, это что-то вроде:

$foo = 1;
$bar = 1;

($foo = $foo + $bar) == ($bar = $foo);

Чтобы понять почему, посмотрите на это

A -> ($foo = $foo + $bar)
B -> ($bar = $foo);

Если A запускается первым, результат будет 2, а результат B будет равен 2, поэтому они равны, и тест будет true.

Если B запускается первым, результат будет 1, а результат B будет равен 2, поэтому они не равны, и тест будет false.

Но для любого сравнения одного типа (где A является переменной, а не выражением) оно всегда будет рефлексивным.

Таким образом, в общем смысле, A == B не всегда на 100% гарантированно эквивалентно B == A. Для переменных это всегда будет эквивалентно. Но для сложных выражений, связанных с присваиванием или изменением переменных, это может быть не так.

2 голосов
/ 21 января 2011

http://php.net/manual/en/language.operators.comparison.php

Существуют разные операторы, которые вы можете использовать, если хотите сравнить приведение типов в сравнении.== оценивается как истина при равном значении, но не сравнивает тип данных.=== оценивается как истина, когда значения равны, а также типы данных.При использовании последнего рассматривается приведение типа, когда его обычно игнорируют (например, строка, представляющая сравниваемое целое число и целое число).

Порядок логики в условном выражении не должен иметь значения.

2 голосов
/ 21 января 2011

Зависит от того, что происходит между этими двумя вызовами.В противном случае да, это то же самое.Порядок не имеет значения.Использование 2 равно == Строка 1 и целое число 1, вернет true при сравнении.Тип игнорируется, сравнивается только значение.Так что нет странностей.

http://php.net/manual/en/language.operators.comparison.php

<?

$a=(string) 1;
$b=(int) 1;

var_dump($a);
var_dump($b);


echo $a==$b;

Выходы: 1

http://www.ideone.com/JLJWQ

РЕДАКТИРОВАТЬ

Для пояснения, вы абсолютно ничего не можете положить в $ a или $ b, чтобы получить другой результат сравнения, просто поместив его на другой стороне оператора.

$a="1234";
$b="1234";

echo $a==$b;
echo $b==$a;

Вывод этого для любых значений $ a или $ b всегда будет без сомнения истинным истинным или ложным ложным.

1 голос
/ 21 января 2011

Я пробовал несколько вариантов и не могу найти случай, когда ($a == $b) !== ($b == $a), но ни один из них до сих пор не работал:

<?php

$a = 0;
$b = "0";

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";

$a = 0;
$b = NULL;

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";

$a = 0;
$b = false;

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";

$a = false;
$b = NULL;

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";

$a = "";
$b = NULL;

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";

$a = "NULL";
$b = NULL;

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";

$a = 0.000000000000000000000000001;
$b = 0;

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";

$a = array();
$b = array();

echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";

Итак, я сдаюсь в этой точке. Идеи приветствуются!

...