PHP rechnet seltsam?

multimolti

Erfahrenes Mitglied
Moin Leute.

Hab eben in der Signatur von jemandem diesen Code gefunden:
PHP:
<? echo 1117407844.92 - 1117407844; ?>
Sollte eigentlich 0.92 ausgeben, gibt aber in Wirklichkeit 0.920000076294 aus. Warum das? Kommt das irgendwie von der Konvertierung von verschiedenen Datentypen ineinander?
So von float in double oder sowas?
 
Hallo,

die Darstellung von Gleitkommazahlen nach IEEE 754 unterliegt stets einer gewissen Ungenauigkeit. Deshalb kommt es hier zu scheinbaren Fehlern, die immer wieder für Verwirrung sorgen. Das ist einfach eine Eigenschaft dieser Darstellung und hat an sich nichts mit PHP zu tun.

Grüße,
Matthias
 
Die beiden Teile können separat berechnet werden:
PHP:
function sub( $minuend, $subtrahend ) {
	switch( (is_float($minuend)?'1':'0').(is_float($subtrahend)?'1':'0') ) {
		case '00':
			return $minuend-$subtrahend;
		case '01':
			$subParts = explode('.', $subtrahend);
			$format = '%d.%0'.strlen($subParts[1]).'d';
			return (float) sprintf($format, $minuend-$subParts[0], $subParts[1]);
		case '10':
			$minParts = explode('.', $minuend);
			$format = '%d.%0'.strlen($minParts[1]).'d';
			return (float) sprintf($format, $minParts[0]-$subtrahend, $minParts[1]);
		case '11':
			$minParts = explode('.', $minuend);
			$subParts = explode('.', $subtrahend);
			$minParts[1] = str_pad($minParts[1], strlen($subParts[1]), '0', STR_PAD_RIGHT);
			$subParts[1] = str_pad($subParts[1], strlen($minParts[1]), '0', STR_PAD_RIGHT);
			if( $minParts[1] < $subParts[1] ) {
				$format = '-%d.%0'.strlen($minParts[1]).'d';
				return (float) sprintf($format, $minParts[0]-$subParts[0], abs($minParts[1]-$subParts[1]));
			} else {
				$format = '%d.%0'.strlen($minParts[1]).'d';
				return (float) sprintf($format, $minParts[0]-$subParts[0], abs($minParts[1]-$subParts[1]));
			}
	}
}

Nachtrag: vergesst die Funktion, die ist Müll.
 
Ich glaube da irrst du dich. Die precision-Direktive bezieht sich nur auf die Anzahl an gültigen Ziffern, die bei der Ausgabe einer Gleitkommazahl maximal angezeigt werden. Die interne Darstellungsgenauigkeit lässt sich zumindest auf diese Weise nicht beeinflussen.

<edit>
aber warum bei dieser Zahl, und z.B. bei <? echo 5 - 3.2; ?> nicht?
PHP:
<?php
printf("%.20f", 5-3.2);
?>
PHP „schummelt“ bei der Ausgabe von Gleitkommazahlen ein bisschen.
</edit>

Grüße,
Matthias
 
Zuletzt bearbeitet:
Da ich damals viel Zeit daran verloren hatte, forschte ich auch weiter nach. Im endeffekt ist es ein Bit-rechenfehler der bei der Konvertierung zwischen den Datentypen zustande kommt.

Google rechnet es btw auch so:
http://www.google.com/search?ie=UTF-8&gfns=1&q=1117407844.92+-+1117407844

Die Lösung war bei mir im endeffekt einfach da ich mit sicherheit wusste das es nur 2 Nachkommastellen geben kann. Leider war der Rechenfehler an der Possition nicht so einfach zu finden da PHP Natürlich hier noch alles richtig machte und erst viel viel weiter unten im Code wo er restframes zusammenrechnete in Endlosschleifen geriet weil er in festen Zeiten Korrekturen vornahm um Werbung zu ganz bestimmten Zeiten abzuspielen.
 
Zurück