2016-06-07 24 views
0

Erstens: Ich bin ein MySql-Neuling und es sieht so aus, als ob ich hier etwas Wichtiges verpasse.MySQL (MariaDB) Float-Visualisierung: Warum sind Werte auf Hunderte oder Tausende gerundet?

In einer MySQL-Datenbank reichen meine Float-Werte von Einheiten bis Milliarden. Ich verbrachte Tage damit, zu verstehen, warum alle von ihnen nicht zeigten mehr als 6 signifikante Stellen mit den weniger signifikant denjenigen auf 0:

dh:

select `field` from `table`; 
(instead of X -> i get Y) 
    1 -> 1 
    12 -> 12 
    123 -> 123 
    1234 -> 1234 
    12345 -> 12345 
    123456 -> 123456 
    1234567 -> 1234570 
    12345678 -> 12345700 
    123456789 -> 123457000 

Nur mit einem „Trick“ fand ich irgendwo I könnte die reellen Werte lesen:

Meine Fragen: Was ist der Grund für dieses seltsame Verhalten (imho)? und wo ist es in der Dokumentation beschrieben? Ich finde völlig nicht intuitiv, dass ich den echten Wert (natürlich nach IEEE-Spezifikationen angenähert) nicht mit der normalen Auswahl * sehe, aber ich brauche den Trick ... Was fehlt mir hier?

+0

Könnten Sie bitte eine [mcve], z. Kopieren/Einfügen einer kompletten MySQL-Sitzung von der Tabellenerstellung bis zur Datenauswahl? Vielleicht demonstrieren Sie sogar mit einem [sqlfiddle] (http://sqlfiddle.com), ob die Ausgabeformatierung es erlaubt, dieses Problem zu demonstrieren? – eggyal

+0

@eggyal, hier ist das minimale Beispiel: http://sqlfiddle.com/#!9/352bf/1/0 Ab ID6 wird das Ergebnis auf 6 sinnvolle Ziffern gerundet. Das Problem ist, dass ich mit "select *" standardmäßig den gerundeten Wert sehen werde, nicht den echten ... Ich nehme an, es gibt einen Befehl, um die db so einzustellen, dass sie den "echten" Wert verwendet, aber nicht verstehen kann Was ist der Grund für diese seltsame Entwicklerwahl? –

+0

Gerade versucht auf SQLfiddle: mit _double_ statt _float_ funktioniert perfekt. –

Antwort

2
  • A FLOAT hat 24 Bits oder log10(224) (über 7) Ziffern, von Bedeutung: 12345678.910 in einem FLOAT gespeichert ist, als 1011110001100001010011112 (die 1234567910). Bei der Anzeige als Dezimalzahl weiß der Client für bestimmte, dass alles von der 8. Stelle definitivfalse precision ist (da ein FLOAT nur 7 Dezimalstellen der Genauigkeit speichern konnte). Es verwirft daher den Rest und lässt Sie mit.

  • A DOUBLE hat 53 Bits oder log10(253) (fast 16) Ziffern, von Bedeutung: 12345678.910 in einem DOUBLE gespeichert ist, als 101111000110000101001110.111001100110011001100110011012 (die 12345678.9000000003710). Bei der Anzeige als Dezimalzahl weiß der Client für bestimmte, dass alles ab der 16. Stelle definitivfalse precision ist (da eine DOUBLE nur 15 Dezimalstellen der Genauigkeit speichern konnte). Es verwirft daher den Rest und lässt Sie mit 12345678.9000000.

Wenn +0.0 Hinzufügen wirft MySQL zuerst die FLOAT bis zu einem DOUBLE.

+0

Danke @eggyal. Ich schrieb das gleiche, als ich deine Antwort erhielt. Das Problem ist, dass ich die IEEE754-Darstellung übersehen habe, wie Sie angemerkt haben. Selbst wenn ich die doppelte Konvertierung mit +0.0 erzwinge, lese ich die zusätzlichen Ziffern, aber da sie als Float gespeichert wurden, sind sie natürlich nicht präzise. Danke. –

+0

@AlexPoca: Eigentlich ist es interessant, dass Sie (unnötigerweise) eine Dezimalziffer auf dem Weg verlieren. Während die Mantisse eines "FLOAT" nur 23 Speicherbits belegt, wird das höchstwertige Bit nicht explizit gespeichert, so dass Sie tatsächlich 24 Bits (oder 7 Ziffern) von Bedeutung haben, wie in meiner Antwort angegeben. Wenn es nur 23 Bits von Bedeutung gäbe, gäbe es nicht genügend Informationen, um die Richtigkeit der 7. Ziffer zu garantieren - und folglich müsste man das auch fallen lassen. Es scheint, dass die Dezimalumwandlung fälschlicherweise 23 anstelle von 24 Bits annimmt: ein Fehler. – eggyal

+0

@AlexPoca: [Ich stehe behoben] (http://Stackoverflow.com/q/29510356). – eggyal

0

Ich habe die Darstellung von Float und Double nach IEEE754 übersehen und das ist die Lösung dieses Geheimnisses.

FLOAT (32 Bit) hat eine Mantisse von 23 Bit (8 Millionen mögliche Werte => 6 sinnvolle Ziffern), die anderen 9 Bit werden für Vorzeichen und Exponent verwendet. DOUBLE (64 Bit) hat eine Mantisse von 52 Bit (etwa 4.5e15 mögliche Werte => 14 aussagekräftige Ziffern).

Das bedeutet Mysql nicht etwas zeigen können, die (in meinem Fall FLOAT große Zahlen) nicht da ist, und füllt die „random“ nicht sinnvoll Ziffern mit Nullen.