Я видел эту небольшую часть кода, которая уклоняется от моего понимания:
<?php $a = '0e462097431906509019562988736854'; $b = '0e830400451993494058024219903391'; var_dump($a == $b);
Что будет выводить:
bool(true)
Я понимаю, что при использовании ==
PHP будет пытаться нечеткое сравнение, без малейшего преобразования между типами для выполнения сравнения. Я не понимаю, почему PHP, похоже, думает, что эти две строки одинаковы. Я бы подумал, так как $a
и $b
являются строками, что преобразование типа не должно происходить.
Что я не понимаю?
Я думаю, эта статья объясняет это довольно хорошо:
Операторы сравнения типа-принуждения преобразуют числовые строки в числа
Просто процитируем главный вопрос здесь:
Согласно php language.operators.comparison , операторы сравнения типа принуждения будут принуждать оба операнда к float, если они оба выглядят как числа, даже если они оба уже являются строками:
где обе strings
используют экспоненциальную нотацию, поэтому рассматриваются как числовые строки, делая свободное сравнение ( ==
), принуждая эти strings
floats
прежде чем фактически «свободно» их сравнивать.
В качестве наилучшей практики и предотвращения неожиданного поведения всегда старайтесь использовать равенство идентичности ( ===
), особенно при работе со strings
На самом деле это не ответ, но если вы попробуете:
$a = '0e4620974319065090195629887368549'; $b = '0e8304004519934940580242199033918'; echo floatval($a) . '<br>' . floatval($b);var_dump($a == $b);
Вы получаете:
0
0
BOOL (истина)
Теперь, если вы попробуете:
$a = '0e4620974319065090195629887368549'; $b = '1e8304004519934940580242199033918'; echo floatval($a) . '<br>' . floatval($b);var_dump($a == $b);
Вы получаете:
0
INF
BOOL (ложь)
Я предполагаю, что PHP преобразует строки в float и дает результат сравнения, используя полученные поплавки, которые в любом случае не верны, но это еще одна история.
В официальной документации проверка равенства между двумя vairiables производится следующим образом:
$a == $b # Equal TRUE if $a is equal to $b after type juggling.
Пример :
$a = 13; # integer type $b = "13"; # string type var_dump($a == $b); # will say TRUE, because juggling was made var_dump($a === $b); # will say FALSE, because PHP will also evaluate the type of variables :)
PHP пытается преобразовать в тип float, потому что строка начинается с 0. Она останавливается после 0, потому что следующий символ не является числом. То же самое происходит, когда вы используете принуждение типа для преобразования научной нотации в integer:
$x = (float)"12E-1x"; // $x == 1.2 $x = (int)"12E-1x"; // $x == 12 (stops at E because it's not an integer)