Vergleich zwischen zwei Strings: Typkonvertierung zu float

Vergleich zwischen zwei Strings: Typkonvertierung zu float

am 14.10.2006 18:13:15 von Jan-Christoph Ihrens

Hallo,

obwohl ich bereits seit geraumer Zeit mit PHP arbeite und mir die
automatische Typ-Konvertierung selbstverständlich vertraut ist, bin ich
heute über einen Fall gestolpert, der mich doch etwas erstaunt. Ich hatte
eine Liste erstellt, in der u. a. mit Hex-Werten gearbeitet wurde. Es
sollte bei jedem fortlaufend generierten Hex-Wert mittels in_array() ein
Vergleich mit den in einem Array gespeicherten Hex-Werten vorgenommen
werden. Die Hex-Werte waren jeweils als Strings definiert (generiert aus
dem zugehörigen Integer-Wert):

$hex_value = sprintf("%04X", $dec_value);

Extrahiert habe ich nach einigen Tests folgende kleine Demo:


$var1 = '00E0'; // Werte '0000' und '00E0' bis '00E9'
$var2 = '00E1';

echo '

Variable 1: "'.$var1
.'", Typ: '.gettype($var1)."

\n";
echo '

Variable 2: "'.$var2
.'", Typ: '.gettype($var2)."

\n";

if ($var1 == $var2) {
echo "

Gleich!

\n";
} else {
echo "

Ungleich!

\n";
}
?>


Das Skript gibt Folgendes aus:


Variable 1: "00E0", Typ: string
Variable 2: "00E1", Typ: string
Gleich!


Was passiert, ist offensichtlich: '00E0' bis '00E9' werden als
Fließkommazahlen in Exponentialschreibweise interpretiert. Das würde mich
auch nicht wundern, wenn irgendwo mit den Werten gerechnet würde oder der
Vergleich zwischen einem String und einem Zahlenwert durchgeführt würde.
PHP selbst bestätigt aber, dass es sich bei beiden Werten um Strings
handelt. Warum also die Typumwandlung???

Ein Vergleich mittels des Operators === führt hier zu einem korrekten
Ergebnis, was einem bei in_array() - auch bei Verwendung des
strict-Parameters (in_array($needle, $haystack, true)) - jedoch nicht
weiterhilft.

Ich habe das Problem durch Programmieren einer kleinen Funktion, die
in_array() ersetzt, umgehen können, wüsste aber dennoch gern, warum es zu
dem beschriebenen Effekt kommt.

Danke schon mal im Voraus!

Gruß,
Jan

Re: Vergleich zwischen zwei Strings: Typkonvertierung zu float

am 14.10.2006 19:00:24 von Ulf Kadner

Jan-Christoph Ihrens wrote:

> > $var1 = '00E0'; // Werte '0000' und '00E0' bis '00E9'
> $var2 = '00E1';
>
> echo '

Variable 1: "'.$var1
> .'", Typ: '.gettype($var1)."

\n";
> echo '

Variable 2: "'.$var2
> .'", Typ: '.gettype($var2)."

\n";
>
> if ($var1 == $var2) {
> echo "

Gleich!

\n";
> } else {
> echo "

Ungleich!

\n";
> }
> ?>
>
>
> Das Skript gibt Folgendes aus:
>
>
> Variable 1: "00E0", Typ: string
> Variable 2: "00E1", Typ: string
> Gleich!

So sollte es sein ja.

> Was passiert, ist offensichtlich: '00E0' bis '00E9' werden als
> Fließkommazahlen in Exponentialschreibweise interpretiert.

Der Numerische Vergleich hat eine größere Priorität wie der Stringvergleich.

Wenn Du sicherstellen wilst das immer typebezogen verglichen wird nutze
=== resp. !== oder bei strings strcmp()

MfG, Ulf

Re: Vergleich zwischen zwei Strings: Typkonvertierung zu float

am 14.10.2006 19:32:53 von Jan-Christoph Ihrens

Am Sat, 14 Oct 2006 19:00:24 +0200 schrieb Ulf Kadner:

> Der Numerische Vergleich hat eine größere Priorität wie der Stringvergleich.

Stimmt, die entsprechende Stelle im Manual habe ich nun auch gefunden.
Danke für den Hinweis!

> Wenn Du sicherstellen wilst das immer typebezogen verglichen wird nutze
> === resp. !== oder bei strings strcmp()

Das ist soweit klar und wird bei Prüfung auf Gleichheit bzw. Ungleichheit
von mir auch so praktiziert. Bzgl. in_array() mit strict-Parameter habe ich
mich ein wenig durch den umgebenden Code verwirren lassen (ich hatte
weitere Tests mit array_search() durchgeführt, dort dann aber den
strict-Parameter vergessen).

Vielen Dank für Deine Antwort!

Gruß,
Jan

Re: Vergleich zwischen zwei Strings: Typkonvertierung zu float

am 14.10.2006 21:17:01 von Niels Braczek

Jan-Christoph Ihrens schrieb:

> Variable 1: "00E0", Typ: string
> Variable 2: "00E1", Typ: string
> Gleich!
>=20
> Was passiert, ist offensichtlich: '00E0' bis '00E9' werden als
> Fließkommazahlen in Exponentialschreibweise interpretiert.

Nein. Beide werden als Integer interpretiert. Diese Interpretaition
bricht bei der ersten Nicht-Ziffer ab. Probiere dazu mal

"01E3" == 1 bzw. "01E3" == 1000

aus.

> Ich habe das Problem durch Programmieren einer kleinen Funktion, die
> in_array() ersetzt, umgehen können, wüsste aber dennoch gern, warum=
es zu
> dem beschriebenen Effekt kommt.

Das Problem entsteht viel früher ist hauptsächlich konzeptioneller Ar=
t.
Welchen Sinn hat es, eine Zahl in einer ihrer unendlich vielen
String-Repräsentation zu speichern? Benutze einfach die Zahl und kodier=
e
sie ggf. bei der Ausgabe.

MfG
Niels

--=20
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------