Die Antwort darauf ist "überraschend" einfach:
Erstens reicht - wie die meisten von Ihnen vielleicht wissen - eine 32-Bit-Ganzzahl von –2.147.483.648 bis 2.147.483.647 . Was passiert also, wenn PHP ein Ergebnis erzielt, das GRÖSSER ist?
Normalerweise würde man einen sofortigen "Überlauf" erwarten, wodurch 2.147.483.647 + 1 zu -2.147.483.648 werden . Dies ist jedoch NICHT der Fall. Wenn PHP auf eine größere Zahl stößt, wird FLOAT anstelle von INT zurückgegeben.
Wenn PHP auf eine Zahl stößt, die über die Grenzen des Integer-Typs hinausgeht, wird sie stattdessen als Float interpretiert. Außerdem gibt eine Operation, die zu einer Zahl führt, die über die Grenzen des Integer-Typs hinausgeht, stattdessen einen Float zurück.
http://php.net/manual/en/language.types.integer.php
Das heißt, und zu wissen, dass die Implementierung von PHP FLOAT dem IEEE 754-Format mit doppelter Genauigkeit folgt, bedeutet, dass PHP in der Lage ist, Zahlen bis zu 52 Bit zu verarbeiten, ohne an Genauigkeit zu verlieren. (Auf einem 32-Bit-System)
An dem Punkt, an dem Ihre Summe 9.007.199.254.740.992 erreicht (das sind 2 ^ 53 ), ist der von PHP Maths zurückgegebene Float-Wert nicht mehr genau genug.
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000000\"); echo number_format($x,0);"
9.007.199.254.740.992
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000001\"); echo number_format($x,0);"
9.007.199.254.740.992
E:\PHP>php -r "$x=bindec(\"100000000000000000000000000000000000000000000000000010\"); echo number_format($x,0);"
9.007.199.254.740.994
Dieses Beispiel zeigt den Punkt, an dem PHP an Genauigkeit verliert. Zuerst wird das letzte signifikante Bit gelöscht, wodurch die ersten beiden Ausdrücke zu einer gleichen Anzahl führen - was sie nicht sind.
Ab JETZT wird die gesamte Mathematik schief gehen, wenn mit Standarddatentypen gearbeitet wird.
• Ist es das gleiche Problem für andere interpretierte Sprachen wie Python oder Perl?
Das glaube ich nicht. Ich denke, dies ist ein Problem von Sprachen, die keine Typensicherheit haben. Während ein Integer-Überlauf wie oben erwähnt in jeder Sprache auftritt, die feste Datentypen verwendet, versuchen die Sprachen ohne Typensicherheit möglicherweise, dies mit anderen Datentypen abzufangen. Sobald sie jedoch ihre "natürliche" (vom System vorgegebene) Grenze erreicht haben, können sie alles zurückgeben, aber das richtige Ergebnis.
Jede Sprache kann jedoch unterschiedliche Threadings für ein solches Szenario haben.