Kraft, PHP integer-überlauf
Wir haben einige integer-Arithmetik, die historische Gründe hat, um die gleiche Arbeit auf PHP-wie in einigen statisch typisierten Sprachen. Seit wir das Letzte mal aktualisiert PHP das Verhalten zum überlaufen ganze zahlen geändert hat. Im Grunde sind wir mit der folgenden Formel:
function f($x1, $x2, $x3, $x4)
{
return (($x1 + $x2) ^ $x3) + $x4;
}
Jedoch, selbst bei Umbauten:
function f($x1, $x2, $x3, $x4)
{
return intval(intval(intval($x1 + $x2) ^ $x3) + $x4);
}
Ich bin immer noch am Ende mit der komplett falsche Nummer...
Beispielsweise mit $x1 = -1580033017, $x2 = -2072974554, $x3 = -1170476976) und $x4 = -1007518822, dass ich am Ende mit -30512150 in PHP und 1617621783 in C#.
Nur die addition von $x1 $x2 ich kann nicht die richtige Antwort:
In C# bekomme ich
(-1580033017 + -2072974554) = 641959725
In PHP:
intval(intval(-1580033017) + intval(-2072974554)) = -2147483648
das ist das gleiche wie:
intval(-1580033017 + -2072974554) = -2147483648
Ich bin nicht dagegen, das schreiben eines "IntegerOverflowAdd" - Funktion oder so etwas, aber ich kann nicht ganz herausfinden, wie (-1580033017 + -2072974554) entspricht 641959725. (Ich erkenne, dass es ist -2147483648 + (2 * 2^31), aber -2147483648 + 2^31 ist -1505523923, die größer ist als Int.Min also, warum fügen Sie 2*2^31 und 2^31?)
Jede Hilfe würde geschätzt...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Also ich habe das problem gelöst, und entdeckt eine Menge über PHP (mindestens in der Art der Verarbeitung von Integer-überlauf).
1) Es komplett hing am Kreuz zwischen welcher Plattform wurde die Maschine läuft, welche PHP version, ob oder nicht es hatte Suhosin-Hardened PHP läuft, und wie viele bits es kompiliert wurde (32 oder 64). 6 Maschinen verhielten sich die Weise, die ich erwartet hatte (das war eigentlich falsch, zumindest schief nach deren Dokumentation) und 3 Maschinen verhielten sich in einer Weise, die ich noch nicht erklären kann, und 3 Maschinen brav nach, was die intval-Befehl sagt, es tut in der Dokumentation.
2) Intval soll zurück PHP_INT_MAX, wenn int > PHP_INT_MAX (nicht int & 0xffffffff), das passiert aber nur bei einigen Versionen von PHP4 und PHP5. Verschiedene PHP-Versionen unterschiedliche Werte zurückgeben, wenn int > PHP_INT_MAX.
3) kann Der folgende code zurück 3 verschiedene Ergebnisse (siehe 1):
Zurück (was zu sein scheint das richtige für Intval aber falsch für & 0xffffff)
Und es zurückgeben kann (das widerspricht der PHP-Dokumentation für intval):
- Und auf 64-Bit-Maschinen, die es gibt (was richtig ist):
Lösung
Jedenfalls, brauchte ich eine Lösung, die funktionieren würde, auf all diesen Plattformen, und nicht abhängig sein von Eigenheiten einer bestimmten version von PHP kompilieren mit einer bestimmten Max. int. So habe ich die cam mit dem folgenden cross-PHP thirtyTwoBitIntval Funktion:
Kommentar
Denke ich, dass die Entwickler von PHP haben sollte, sagte ein Int ist ein 32-Bit Int, egal ob es auf einem 32-oder 64-oder 128-bit-Computer (wie das DotNet CLR zum Beispiel), und nicht zufällig upconvert es zu einem float-abhängig von der Anzahl der Bits, die PHP-compiler unter.
Wenn Sie möchten, eine 100% funktionierende Lösung für 32-bit-intval sowohl auf 32-und 64-bit-Plattformen, dann schlage ich vor, Sie verwenden die folgende Lösung:
Intern, verwendet PHP eine "integer" - Typ für die meisten zahlen. Allerdings sind diese nur so weit gehen: wenn Sie hinzufügen, eine große Ganzzahl große Ganzzahl, PHP wird sehen, dass das Ergebnis zu groß, um zu passen in eine normale integer und ordnet Sie ein floating-point-Zahl. Floating-point-zahlen (floats) sich nur so hoch gehen, aber, und es gibt einen Punkt, um die sechzehn-stellige Marke, wo wird PHP nur verlieren, den plot komplett.
Gibt es eine option, um beliebige Genauigkeit der Mathematik, die unterstützt zahlen von beliebiger Größe und Genauigkeit, dargestellt als strings. Weitere Informationen finden Sie hier: http://us2.php.net/bc
Ich denke, es kann zu tun haben mit den integer in PHP als vorzeichenlosen 32-bit wie in C# Sie sind vorzeichenbehaftete 32 bit standardmäßig.
Spielen Sie mit zahlen auf dem Rand des normalen 31-32 bits Bereich.
Finden Sie zusätzliche Dokumentation im PHP-Handbuch:
http://www.php.net/manual/en/language.types.integer.php
Die Größe einer ganzen Zahl ist plattformabhängig, ein Maximalwert von ungefähr zwei Milliarden ist jedoch üblich Wert (vorzeichenbehafteter 32-bit). PHP unterstützt keine vorzeichenlosen Integer-Werte. Integer-Größe kann bestimmt werden unter Verwendung der Konstanten PHP_INT_SIZE, und der maximale Wert mit der Konstante PHP_INT_MAX seit PHP 4.4.0 und PHP 5.0.5.
Wird das funktionieren?
Zu generalisieren, die man tun könnte (Entschuldigung für etwaige syntax-Fehler, ich habe nicht berührt, die PHP für eine lange Zeit):
Überprüfen Sie Ihre Versionsnummer von PHP - ich glaube, dass es möglich ist, erhalten Sie unterschiedliche Ergebnisse mit unterschiedlichen Versionen von PHP, können unterschiedliche Unterstützung für lange Ganzzahlen. Ich glaube, dass es ein Fehler war, mit großen zahlen in endlich einer der PHP-5-Versionen.
In der version PHP 5.2.0 - die Antwort ist GENAU die gleiche, wie Sie bekam in C#
1617621783,
unter Verwendung der exakten Funktion, die Sie haben vor.
Können Sie die phpinfo () - Befehl, um Ihre version und-Nummer, einfach.