PHP rundet bzw. kürzt automatisch

NoUse4aNick

Mitglied
Guten Abend zusammen,

Ich habe bereits im IRC versucht eine schnelle lösung zu diesem Problem zu finden, allerdings scheint es doch etwas Problematischer als es scheint.

Das Problem ist das das php script je nach Server auf welchem es ausgeführt wird ergebnisse Entweder rundet, oderetwas weg schneidet(kürzt).

Das Passiert seltsamerweise mit jeder Berechnung die 16 Bit überschreitet.

Fallbeispiel:
PHP:
function Calculate($iCostID) {
    $result = NULL;
	$result = ($iCostID - 0x6073) * 0xEEB9EB65;
    return $result;
}


$CostFOO= 0xF9BF13C0;
$CostFOO= Calculate($CostFOO);
echo '0x'.dechex($CostFOO).'<br />';

Das Ergebniss des Beispieles wäre "0xE8E4AB25BF796C61" würde alles korrekt laufen.

Nun zu den Ergebnissen die ich Bekomme:
-Lokale Xampp Installation: "0x0"
-Webspace: "0xE8E4AB25BF797000"

Ich kürze das ganze mal auf 32 Bit zum erleichterten lesen:
0xBF796C61 <--- Ergebniss Berechnung
0xBF797000 <--- Ergebniss Server

Wie man sieht werden 16bit aufgerundet, aso die letzten 4 stellen.

Wie gesagt ich bin Ratlos. Zum einen Weshalb meine lokale xampp installation 0 ausgibt und zum anderen warum PHP auf dem Server automatisch Rundet.

Ich hoffe ihr könnt mir helfen,
lg NoUse4aNick
 
Guten Morgen,

Danke schonmals für die Information. Das ein überlauf geschieht bei einem normalen Integer, ist in dieser Dimension Klar.
Nun ist die Frage ob man Irgendwie das system anweisen kann statt einem Integer einen long bzw. Unsigned Integer 64bit zu benutzen, da ich leider mit 64Bit Rechnen muss. Bei einer Google suche, habe ich nur gesehen das sehr viele dies umgehen indem sie Teilergebnisse nehmen und diese dann wie eine Stringkette zusammensetzen. Ich kann meine Berechnungen aber leider nicht in Teilschritte zerlegen.

liebe Grüße
NoUse4aNick
 
Du kannst ev. die Variabl als Long instanzieren
PHP:
$long = (Long) 0;
$long = ((Long) $x) * ((Long) $y);
 
Danke für den ansatz mit long,

allerdings hatt das auch nicht wirklich etwas bewirkt. Einzige änderung: Der Code wird unschön zu lesen. Die ergebnisse bleiben die selben.

Ich habe die Funktion Folgendermasen Abgeändert, vlt habe ich ja etwas falsch verstanden...:
PHP:
		$result = (long) 0;
	$result = (long)(((((long) $iCostID) * ((long) 0x41C64E6D)) + ((long) 0x6073)) & ((long)0xFFFFFFFF));
	return $result;

Auf Meiner Suche durch das WWW bin ich auf PHP_INT_MAX gestoßen. Allerdings finde ich nirgendwo wie ich den wert definieren kann. In der PHP.ini ist ein solcher eintrag leider nicht verhanden.
 
Danke schonmals für die Information. Das ein überlauf geschieht bei einem normalen Integer, ist in dieser Dimension Klar.
Nun ist die Frage ob man Irgendwie das system anweisen kann statt einem Integer einen long bzw. Unsigned Integer 64bit zu benutzen, da ich leider mit 64Bit Rechnen muss. Bei einer Google suche, habe ich nur gesehen das sehr viele dies umgehen indem sie Teilergebnisse nehmen und diese dann wie eine Stringkette zusammensetzen. Ich kann meine Berechnungen aber leider nicht in Teilschritte zerlegen.
Hast du dir meinen Link mal angeschaut? Auf der Seite wird sowohl auf GMP als auch auf BC Math verwiesen.

Grüße,
Matthias
 
Hast du dir meinen Link mal angeschaut? Auf der Seite wird sowohl auf GMP als auch auf BC Math verwiesen.

Grüße,
Matthias

Ja habe ich, allerdings suche ich nach eben einer Art den Server 64Bit tauglich zu machen, eben ohne zwischen funktionen. Per PHP.ini o.Ä

liebe Grüße
NoUse4aNick

Edit: GMP bekommt seltsamerweise ebnfalls einen überlauf. BCMath funktioniert zwar, allerdings besitzt diese methode keine AND verknüpfung und ist daher wertlos.
 
Zuletzt bearbeitet:
Ja habe ich, allerdings suche ich nach eben einer Art den Server 64Bit tauglich zu machen, eben ohne zwischen funktionen. Per PHP.ini o.Ä
Das funktioniert prinzipiell nicht.

Edit: GMP bekommt seltsamerweise ebnfalls einen überlauf.
Quellcode bitte.

BCMath funktioniert zwar, allerdings besitzt diese methode keine AND verknüpfung und ist daher wertlos.
Das ließe sich zur Not auch über die angebotenen Operationen realisieren.

Grüße,
Matthias
 
Na irgendwo muss doch festgelegt werden was PHP_INT_MAX ist, von daher müsste es dch möglich sein auch diesen Wert zu verändern...oder?

Quelltext zu GMP:
PHP:
function RevGMP ($CostID) {
//Originalrechnung: (($CostID - 0x6073) * 0xEEB9EB65) & 0xFFFFFFFF;
	$result = 0;
	$multiplier = "4005161829"; // = 0xEEB9EB65 Da weder das direkte angeben des wertes noch das casten von dechex angenommen wird
	$substracter = "24691"; //= 0x6073
	$modulant = "4294967295"; // = 0xFFFFFFFF
	$result = gmp_sub($CostID,$substracter);
	$result = gmp_mul($result,$multiplier);
	$result = gmp_and($result, $modulant);
	echo "0x".gmp_strval($result,16)."<br />";// sollte 0xC9AECE02 als ergebniss liefern, liefert aber 0x9b7b763c
	return gmp_strval($result);

}
 
Na irgendwo muss doch festgelegt werden was PHP_INT_MAX ist, von daher müsste es dch möglich sein auch diesen Wert zu verändern...oder?
Natürlich. Aber diese Festlegung findet beim Kompilieren von PHP statt und kann zur Laufzeit nicht beliebig verändert werden.

Quelltext zu GMP:
PHP:
function RevGMP ($CostID) {
//Originalrechnung: (($CostID - 0x6073) * 0xEEB9EB65) & 0xFFFFFFFF;
	$result = 0;
	$multiplier = "4005161829"; // = 0xEEB9EB65 Da weder das direkte angeben des wertes noch das casten von dechex angenommen wird
Wenn du die Konstanten hexadezimal notieren willst, solltest du gmp_init verwenden.

PHP:
	$substracter = "24691"; //= 0x6073
	$modulant = "4294967295"; // = 0xFFFFFFFF
	$result = gmp_sub($CostID,$substracter);
	$result = gmp_mul($result,$multiplier);
	$result = gmp_and($result, $modulant);
	echo "0x".gmp_strval($result,16)."<br />";// sollte 0xC9AECE02 als ergebniss liefern, liefert aber 0x9b7b763c
	return gmp_strval($result);

}
Wie genau rufst du die Funktion auf?

Grüße,
Matthias
 
Zurück