[vsprintf] %d max 2,xx Mrd

Bububoomt

ohne Vertrauen
ID: 10361
L
28 April 2006
19.666
769
Alos ich benutze schon seit langem vsprintf und %d für Int (auch bei großen zahlen) bisher Problemlos.

Nach einem Serverumzug trägt er nur noch 2,xx Mrd in die db.

Nee Idee woran es liegt? Neue PHP version? Irgend eine Einstellung?
Wäre eniges an Aufwand wenn ich aus %d jetzt überall etwas anderes machen müßte . (was wäre das passende für bigint?)
 
%d formatiert Integer und die gehen eben nur auf 31bit (1bit sign-flag) = 2.147.483.647; darüber hinaus gibts n Überlauf.

Entweder unsigned nehmen, d.h. 32bit bis 4.294.967.295 oder auf 64bit-Datentypen gehen.
 
frage mich wieso es aufm alten server ging, da gabs selbst bei 10 Mrd kein Problem.

unsigned wäre %u, aber im grunde ist das auch zu wenig für ein Lose-Feld.

was wäre denn mehr? %f oder?

hm dann muß ich ja jetzt alles durchgehen und ändern :(
 
Und was wäre mehr?
%I64d - das gibt es aber auf PHP nicht, sondern wird von der C-sprintf()-Funktion unterstützt (Frag mich aber nicht, ob das standardisiertes C is).

In PHP, hab eben nochmal nachgelesen, um dir nix falsches zu erzählen, geht nicht mehr als PHP_INT_MAX:
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.
Quelle: https://de2.php.net/manual/de/language.types.integer.php

Wie du aus den Userkommentaren entnehmen kannst, und ich hab da vorsichtshalber auch im PHP-Source nachgesehen, arbeitet PHP mit ganz normalen C-ints, d.h. auf einer 64bit-Architektur kompiliert, kannst du ganz "normal" das volle Spektrum von -9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807 ausnutzen.
AMD Athlon(tm) 64 X2 Dual Core Processor 3400+
Genau sowas :yes: :biggrin:
 
Oh Man,
never change a running system... ;)

Mal sehen ob ichs am frühen morgen (Für sSamstags ist es früh ;) ) verstadnen habe.

Ich habe 64 Bit Prozessor,aber scheinbar wurde das php auf nem 32 Bit compiliert und daher ist 2,4 mrd das maxmum.
 
Ich habe 64 Bit Prozessor,aber scheinbar wurde das php auf nem 32 Bit compiliert und daher ist 2,4 mrd das maxmum.
Das is zumindest meine Vermutung. Probiers halt mal aus und kompilier PHP neu auf deiner 64bit-Maschine. Du musst es ja nicht groß installieren, sondern reicht ja, von der Konsole aufzurufen und gucken, ob
Code:
[FONT=Lucida Console]php -r "echo sprintf('%u', 9999999999);"[/FONT]
die gewünschte Ausgabe bringt.
 
er kann doch %f mit 0 Nachkommastellen nutzen, sollte glaube ich so heißen:
Code:
%.0f

Die Dezimalstellen weisen ja bei Floats meines Wissens keine Ungenauigkeit auf, das betrifft ja immer nur die Nachkomastellen.
 
Die Dezimalstellen weisen ja bei Floats meines Wissens keine Ungenauigkeit auf, das betrifft ja immer nur die Nachkomastellen.
Du weißt aber schon, was Floating-Point is? 8O
Sobald die Zahlen größer werden, d.h. der Exponent größer wird, die Mantasse die höheren Stellen abdeckt, wird folglich hinten die kleineren Stellen abgeschnibbelt. Für Lose kannst du das nicht benutzen.

Da gucken einige ganz schön dumm, wenn ihr Guthaben mal eben um ein paar Tausend Lose abgerundet wird :LOL:
 
Du weißt aber schon, was Floating-Point is? 8O
Sobald die Zahlen größer werden, d.h. der Exponent größer wird, die Mantasse die höheren Stellen abdeckt, wird folglich hinten die kleineren Stellen abgeschnibbelt. Für Lose kannst du das nicht benutzen.

wenn er in PHP schon Zahlen hat, die größer als ein int sind, was meinst du wohl in welchem System sie vorliegen? ;)
Dementsprechend hat er die Ungenauigkeit schon in seinen Rechnungen, und würde sie mit einem %.0f nur an die Ausgabe (Umwandlung in einen String für die db) weiterreichen :p
 
wenn er in PHP schon Zahlen hat, die größer als ein int sind, was meinst du wohl in welchem System sie vorliegen? ;)
Dementsprechend hat er die Ungenauigkeit schon in seinen Rechnungen, und würde sie mit einem %.0f nur an die Ausgabe (Umwandlung in einen String für die db) weiterreichen :p

Naja Loseseiten müssen mit einem hohen Dynamikbereich rechnen: Vom User der für einen Bannerklick ein paar Dutzend Lose bekommt (Zahl aus der Luft gegriffen) bis zum Schieber der ein paar Dutzend Milliarden hin und her verschieben will. Da sollte schon für alle die Rechnung auf 1 Los genau sein (sonst findet sich jemand der die Rundung zum eigenen Vorteil ausnutzt und damit "reich" wird).

Du weißt aber schon, was Floating-Point is? 8O
Sobald die Zahlen größer werden, d.h. der Exponent größer wird, die Mantasse die höheren Stellen abdeckt, wird folglich hinten die kleineren Stellen abgeschnibbelt. Für Lose kannst du das nicht benutzen.

Float reicht nicht, aber double könnte reichen. Das unterstützt eine Mantisse von 52 Bit und sollte so bis etwa 10[sup]16[/sup] noch auf 1 Los genau sein. Solange also niemand mehr als 10 Billiarden Lose hat... :biggrin:

Obschon 64 Bit Integer die sauberere Lösung wäre, denn eigentlich gibt es ja nur ganzzahlige Lose (und man reicht sogar bis 9 Trillionen). Nur ist man damit offenbar weniger plattformunabhängig...
 
Naja Loseseiten müssen mit einem hohen Dynamikbereich rechnen: Vom User der für einen Bannerklick ein paar Dutzend Lose bekommt (Zahl aus der Luft gegriffen) bis zum Schieber der ein paar Dutzend Milliarden hin und her verschieben will. Da sollte schon für alle die Rechnung auf 1 Los genau sein (sonst findet sich jemand der die Rundung zum eigenen Vorteil ausnutzt und damit "reich" wird).
bestreite ich doch nicht, aber die Standard artihm. Operationen in einem 32Bit PHP gewährleisten dies eben nicht.


Zu 99,99% kommt das wohl aus MySQL und einem BIGINT und das is, wie der Name schon sagt, ein Integer.
ach du bist der Meinung, der Wert wird nur aus MySQL ausgelesen und wieder zurückgeschrieben ohne eine Modifikation zu machen?
Und wenn eine Modifikation gemacht wird, ist es egal welcher Datentyp es in der Db ist, es zählt was PHP macht.

Und da sind wir bei dem Problem was ich versuche zu zeigen: Du kannst die beste Option für sprintf nehmen um möglichst genau zu bleiben, die arithm. Operationen vorher waren aber auf einem 32Bit PHP weshalb der Int zu einem Float umgewandelt wurde und die Genauigkeit schon längst verloren ging :!:
 
So es wurde die 32 statt die 64 Bit version nstalliert, das wirds sein...
Wird nun geändert.
 
Nur nochmal als kleine Aufmerksamkeit: Floating Point Zahlen koennen gerade bei sehr grossen Zahlen auch in den Stellen vor dem Komma gerundet werden:

Wie ich weiter oben im Thread ja auch schon konkretisierte: Bei double precision liegt die Grenze ungefähr bei 10[sup]16[/sup], größere Zahlen sind nicht mehr auf 1 Los genau. Bei single precision weiß ich gar nicht wieviel Bit die Mantisse genau hat, 24? Dann würden wir grade mal von 10[sup]7[/sup] sprechen...

Das Problem ist halt, dass man sich auf solche Angaben nicht verlassen kann, wenn sie maschinenspezifisch sein können. "Auf 64 Bit Integer umstellen" schön und gut aber was mache ich in der Anwendung, wenn die Maschine den nicht unterstützt? Ich weiß nicht ob man sich heute pauschal drauf verlassen kann, dass alle Server 64Bit-Architektur und dazu passende Software haben...