phpbar.de logo

Mailinglisten-Archive

[php] mal was zum raten ...

[php] mal was zum raten ...

Andreas Heigl a.heigl at wdv.de
Fre Apr 29 17:19:51 CEST 2005


Norbert Pfeiffer schrieb:

> Hallo,
> 
> damit niemand uebers WE einrostet:
> 
> In einem Script wird eine(1) csv-Datei eingelesen und verarbeitet.
> Dabei wurden einige Datensaetze nie richtig beruecksichtigt.
> Also habe ich ein zweites "elseif" eingefuegt,
> und siehe da, es klappt - nur warum ... <gruebel>
> 
> 
> <?
> function umform($zahl) {
>     return doubleval(str_replace(',','.',$zahl));
> }
> 
> /* Hier werden Werte erzeugt   */
> $sm19 = 0 + umform($BB[19]);
> $summ = 0 + umform($BB[20]) + umform($BB[21]);
> 
> /* und hier dann verglichen    */
> } elseif ($sm19 == $summ) {
>     $TT[$i] .= ' / Berechnung A';
> } elseif ("$sm19" == "$summ") {
> 
>     $TT[$i] .= ' / Berechnung B';
> }
> ?>
> 
Mal ins Blaue:
Kann es sein, dass im Rahmen von internen Typkonvertierungen da ein
Rundungsfehler Einzug gehalten hat? Oder ein Rundungsfehler beim '==' sich
einschleicht? 

Schau mal hier: 
http://de3.php.net/manual/de/language.types.float.php#warn.float-precision
<snip>
Fließkomma Präzision

 Es ist ziemlich normal, dass einfache Dezimalzahlen wie  0.1 oder 0.7 nicht
in ihre  internen binären Entsprechungen konvertiert werden können, ohne
einen kleinen Teil ihrer Genauigkeit zu verlieren. Das kann zu verwirrenden
Ergebnissen führen. So wird floor((0.1 +  0.7) * 10) normalerweise 7 statt
des  erwarteten Wertes 8 zurück geben (als Ergebnis  der internen
Entsprechung von 7.9999999999...).

 Das gründet sich auf die Tatsache, dass es unmöglich ist, manche
Dezimal-Zahlen durch eine endliche Anzahl an Nachkomma-Stellen
darzustellen. Dem Wert 1/3 entspricht z.B.  der interne Wert von 0.3333333.
. ..

 Deshalb sollten Sie nie den Ergebnissen von  Fließkomma-Operationen bis auf
die letzte Nachkomma-Stelle trauen  und nie solche auf Gleichheit prüfen.
Benötigen Sie wirklich eine  größere Genauigkeit, sollten sie die
mathematischen Funktionen beliebiger  Genauigkeit oder die Gmp  Funktionen
benutzen.
</snip>

Und genau das machst du mit deinem Vergleich aber.

Und im zweiten 'elseif' machst du ja de facto eine Typenvereinheitlichung
auf 'STRING' und vergleichst die dann. Und einem String ist es relativ egal,
wie lang die Zahl ist....

Hast du mal einen Auszug aus deiner CSV-Datei, damit wir wissen, um was für
Daten es sich handelt?

Oder gib doch im 2. 'elseif' mal aus, was für Werte du da vergleichst. Oder
lass dir vor dem Vergelich mal einen Var_dum ausgeben von den beiden
Vergleichszahlen.

Vielleicht solltest du auch einfach nach FLOAT konvertieren und nicht nach
DOBLE?

HTH

Grüße

Andreas
-- 

wdv Medien & Kommunikation GmbH & Co. OHG
Mediendatenverarbeitung
Andreas Heigl
Siemensstrasse 6
61352 Bad Homburg
Germany
Telefon +49-(0)6172-670-185
Telefax +49-(0)6172-670-181
www.wdv.de



php::bar PHP Wiki   -   Listenarchive