2010-11-08 6 views
6

Mögliche Duplizieren:
PHP Math Precision((171.36/1.19) == 144) ist falsch?

Hier ist ein Beispielcode in PHP

echo (171.36/1.19) 
//[PHP] result: 144 
//[JavaScript] result: 144.00000000000003 
//[Manual] result : 144 

$var1 = 144; 
$converted = 171.36/1.19 


//Variable 1 is less than Converted? 
echo (($var1 < $converted)?"Yes":"No") 
//result: Yes 

//Variable 1 is equal to Converted? 
echo (($var1 == $converted)?"Yes":"No") 
//result: No 

echo (($converted == 144)?"Yes":"No") //--> NO 
echo (("144.00" == 144)?"Yes":"No") //--> YES 

Können Sie mir geben, eine einfache Erklärung/Antwort und sagen Sie mir, dass PHP ist nicht Buggy.

+25

Ionisierende Strahlung kann eine CPU verursacht ein falsches Ergebnis zu erzeugen. Ich halte eine Flasche Jodtabletten an meinem Schreibtisch, und nehmen Sie 2 jedes Mal eine Gleitkomma Gleichheitstest fehlschlägt. – mikerobi

+2

Ich dachte, Sie sollten 2,1 Pillen nehmen? Was ist mit der Disparität ??? – webbiedave

Antwort

16

Dies ist das Ergebnis von Gleitkommaberechnungen, die inhärent einen bestimmten Fehlerbetrag beinhalten. Beliebige reelle Zahlen können nicht genau in dem Gleitkommaformat gespeichert werden, das von den meisten Sprachen (einschließlich PHP) verwendet wird. Sie werden ähnliche Ergebnisse in vielen anderen Sprachen sehen.

http://php.net/manual/en/language.types.float.php (lesen Sie die große rosa Kasten)

+1

+1 Wahrscheinlich die beste Antwort des Bündels, wie es auch auf das PHP-Handbuch verweist. – cgp

+0

Ich bin damit einverstanden; +1 für Hinweise auf das PHP-Handbuch, das dieses leider häufig auftretende Missverständnis erklärt. – Randolpho

19

Sie sehen, dass das Ergebnis auf 144 nahe genug ist, dass das ist der Wert angezeigt, wenn Sie es in einen String konvertieren - aber es ist nicht genau 144 weshalb Sie bekommen „NEIN“ auf der vorletzten Zeile .

Dies ist das gleiche Problem mit Fließkommazahlen, die Leute immer wieder und wieder laufen.

Weder 171.36 noch 1.19 können in binären Fließkommatypen genau dargestellt werden. Also verwendet PHP eine sehr gute Annäherung an sie. Wenn Sie arithmetisch arbeiten, wird das Ergebnis so genau sein, wie es sein kann, angesichts der Einschränkungen der beteiligten Datentypen und die ursprünglichen Daten (d. H. "Nicht ganz", was Sie erwartet haben).

Fazit: Vergleichen Sie Gleitkommawerte für Gleichheit nicht direkt, außer unter ganz besonderen Umständen. Normalerweise ist es besser, sie innerhalb einer bestimmten Toleranz zu testen (z. B. der Wert zwischen 144-0.00001 und 144 + 0.00001).

+0

[News Flash: Gleitkommazahlen sind nicht unendlich präzise. Details unter. 10: 05000000004] (http://twitter.com/CrystalEmpGames/status/27160772411) –

1

PHP ist nicht fehlerhaft. Es zeigt 144 nur an, weil es auf 12 signifikante Zahlen abgerundet wird, wenn die Fließkommazahl in eine Zeichenkette zum Drucken umgewandelt wird.

Wenn Sie die Zahl auf 17 Dezimalstellen drucken, sehen Sie das Ergebnis tatsächlich 144.00000000000003, das gleiche wie das Ergebnis von Javascript.

(Die anderen Antworten haben erklärt, warum das Ergebnis nicht genau 144 schon, ich bin es hier nicht gehen zu wiederholen.)

Siehe http://www.ideone.com/u0yB8 für Beispielcode.

5

Von The Floating-Point Guide:

Warum nicht die Zahlen, wie 0,1 + 0,2 summieren sich zu einem schönen runden 0,3 und stattdessen bekomme ich eine seltsame> führen wie 0,30000000000000004?

Da intern verwenden Computer ein Format (binäre Fließkomma), die nicht genau eine Zahl wie 0,1, 0,2 oder 0,3 überhaupt darstellen können.

Wenn der Code kompiliert oder interpretiert wird, wird Ihre "0.1" in diesem Format bereits auf die nächste Zahl gerundet, was bereits vor der Berechnung zu einem kleinen Rundungsfehler führt.

Grundsätzlich, wenn Sie die wörtlichen 171.36 in Ihren Code schreiben, und der Code interpretiert wird, die Anzahl der Computer verwenden werden nicht in der Tat, 171,36 - so ist es keine Überraschung, dass es ein anderes Ergebnis ergeben würde wenn es in einer Berechnung verwendet wird.