phpbar.de logo

Mailinglisten-Archive

[php] Rundenproblem

[php] Rundenproblem

Yannik Hampe yannik at cipher-code.de
Di Mär 30 12:39:31 CEST 2010



Mario Batz wrote:
> Hallo,
> 
> irgend wie stehe ich auf dem Schlauch. Folgendes ist gegeben:
> 
> Entwicklungssystem:
>  - Debian
>  - PHP 5.2.0
> Produktivsystem:
>  - Windows 2003 SBS SP2
>  - PHP 5.2.1
> 
> Es wird ein Array mit Werten aus der DB erzeugt:
> $summen["zw_summe"] = 9.5;
> $summen["ust_prozentwert"][7] = 0.665;
> 
> Ggf. ist noch eine 2. Ebene vorhanden:
> $summen["ust_prozentwert"][19] = 0;
> 
> Wenn ich nun die Unterelemente von "ust_prozentwert" summieren möchte,
> verwendet man ja "array_sum()". Somit ergeben sich aus allen Werten komplett
> eine Summe von "10.165".
> 
> Wenn ich dieses in eine Zeile packe und auf 2 Nachkommastellen runde ...
> round($summen["zw_summe"]+array_sum($summen["ust_prozentwert"],2);
> ... dann hab ich unter Debian die Zahl 10.17
> ... und unter Windooooof 10.16 ?!?!??!?!?!?!
> 
> Rund ich aber das Ergebnis von array_sum() noch vor der Addition mit
> $summen["zw_summe"] ...
> round($summen["zw_summe"]+round(array_sum($summen["ust_prozentwert"]),2),2);
> ... dann bringen beide Systeme 10.17
> 
> Hab ich irgendetwas übersehen? Oder liefert array_sum() unter Windows die
> Zahl so, dass diese plötzlich mathematisch gerundet (bei geraden Zahlen vor
> der 5 wird abgerundet, bei ungeraden vor der 5 wird aufgerundet) wird, so
> wie es Access schon immer macht.
> 
> Mach ich einen Denkfehler? Bug? Feature?

Floats sind ungenau, da einige Zahlen, die im Dezimalsystem nicht
periodisch sind im Dualsystem sehr wohl periodisch sind. Natürlich
sollte der Fehler theoretisch überall gleich sein, allerdings garantiert
php dir das nicht:

"The size of a float is platform-dependent [!!], although a maximum of
~1.8e308 with a precision of roughly 14 decimal digits is a common value
(the 64 bit IEEE format)." (aus der php-doku)

Wenn du mit so etwas kritischem wie Geld rechnest, dann kann ich dir nur
ans Herz legen immer alles in cent zu berechnen und erst bei der Ausgabe
durch 100 zu teilen. Wenn dir das nicht reicht, weil es Zwischenwerte
mit Bruchteilen von cent geben kann, dann muss du dir natürlich was
anderes überlegen. Zum Beispiel die bcmath oder gmp-Funktionen nehmen.
> 
> Mit freundlichen Grüßen
> Mario Batz 

Yannik

php::bar PHP Wiki   -   Listenarchive