PHP: Igual versus Idéntico

Según la documentación de PHP, el operador '==' devuelve verdadero (TRUE) sin sus operandos son iguales, mientras que '===' devuelve verdadero si los operandos son iguales y además del mismo tipo (idénticos).
Recién nos encontramos con que al hacer las comparaciones:
121574312008178411518235 == 121574312008178402299047
121574312008178411518235 === 121574312008178402299047
ambas devuelven verdadero, esto no resulta tan extraño si vemos que el valor "real" de ambos números, que es:
1.2157431200818E+23
Esto significa que estamos comparando:
1.2157431200818E+23 con: 1.2157431200818E+23
Como pueden ver, ambos son "idénticos".
Ahora bien, resulta ser que:
'121574312008178411518235' == '121574312008178402299047'
Ahora sí, esto si resulta extraño.
El problema "real" acá es que como PHP es un lenguaje no tipado (typeless), no hay una forma adecuada de decirle al lenguaje que se trata de un string. Intentamos haciendo typecasting, pero el comportamiento es el mismo.
Usando el operador '===', la siguiente comparación retorna falso:
'121574312008178411518235' === '121574312008178402299047'
Acá está el ejemplo completo:
<?php
echo "<pre>\n";
$a = 121574312008178411518235;
$b = 121574312008178402299047;
if ($a == $b){
printf("$a == $b\n");
} else {
printf("$a != $b\n");
}
if ($a === $b){
printf("$a === $b\n");
} else {
printf("$a !== $b\n");
}
$a = '121574312008178411518235';
$b = '121574312008178402299047';
echo "\n";
if ($a == $b){
printf("$a == $b\n");
} else {
printf("$a != $b\n");
}
if ($a === $b){
printf("$a === $b\n");
} else {
printf("$a !== $b\n");
}
echo "</pre>\n";
?>
Las pruebas fueron realizadas utilizando:
PHP 5.2.5, Apache 2.2.6/Mac OSX 10.5.3 (Leopard)
PHP 5.2.6 Apache 2.2.8/FreeBSD 7.0-STABLE



7 comentarios:
Los enteros en PHP son de 32bits o 64 bits dependiendo del hardware.
De hecho si uno hace:
echo PHP_INT_MAX;
Retorna: 2147483647
Lo que quiere decir que el limite para enteros es:
-2,147,483,647 a 2,147,483,647
Numeros mayores que esos son convertidos a "float" los cuales tienen una precision de 14
digitos por defecto. (php.ini => precision = 14)
En el caso del numero "121574312008178411518235" este se convierte a float debido a que
sobrepasa el maximo de 2,147,483,647, ahora, al convertirse a float y exceder la precision de
14 caracteres se convierte a notacion cientifica.
Se puede extender la precision la precision, ahora esto hace que despliegue
"121574312008178411518235" y no "1.2157431200818E+23" pero el resultado sigue siendo el mismo,
ya que a nivel interno, sigue siendo "1.2157431200818E+23".
Se puede hacer un truco para trabajar con enteros grandes:
1. Usar MySQL para las
select if(121574312008178411518235 <> 121574312008178402299047, 'diferentes', 'iguales');
Ahora para poder hacer:
< ? php
// Extendemos la capacidad de manejar numeros de hasta 30 caracteres
ini_set('precision', '30');
$sql = "select if({$a} <> {$b}, 'diferentes', 'iguales') resultado";
$rs = mysql_query($sql);
$row = mysql_fetch_array($rs);
print_r($row['resultado']); // diferentes
Tienes toda la razón!, por ahí hice la mención que ambos tenían el mismo valor (1.2157431200818E+23), pero que pasa si yo no quiero tratarlo como un número sino como una cadena de caracteres?
Para mí lo lógico sería que al hacer esta asignación:
$a = '121574312008178411518235';
$b = '121574312008178402299047';
sea tomada como un string...
El problema es justamente ese, porque si yo hiciera:
$a = 'A121574312008178411518235';
$b = 'A121574312008178402299047';
el comportamiento que tiene si es el esperado.
Creo que este es un mal generalizado de los lenguajes no tipados, recién probé también en perl (con ==) y el comportamiento es el mismo.
En bash sería una instrucción así:
if [ "X$a" = "X$b" ]; then
....
else
....
fi
... adivinen que? ... en php y en perl sería lo mismo ...
Saludos
Thank you for your help!
rH3uYcBX
Si, probablemente lo sea
Hola.
Antes de nada, perdona que te escriba esto como un comentario, pero es que no vi tu email en el tu blog
Soy el webmaster de publizida.es
Publizida BLOG'S es un ranking / directorio de clasificación de blogs en español, creado con el único propósito de dar a conocer los mejores blog's
Registrando su blog en Publizida BLOG'S accederás al servicio de estadísticas gratuitas y podrás participar en el TOP.RANKING
También puedes acceder a la valoración que los usuarios hacen de su página.
Y lo mas importante...
darte a conocer y aumentar el numero de visitantes a tu BLOG de manera totalmente gratuita.
Si te interesa puedes darte de alta
ALTA DIRECTORIO DE BLOGS
o visitanos en ......
DIRECTORIO DE BLOGS
HTTP://PUBLIZIDA.ES
Muchas Gracias por tu tiempo... y disculpa si no fue la mejor manera de darme a conocer.
Un saludo.
DAVID T.
Webmaster de Publizida.es
Happy New Year[url=http://nfksghjskf.com/],[/url] everyone! :)
Publicar un comentario