Precision, real Datentyp, Verständnisproblem

Ich habe ein Verständnisproblem bei den beiden floating-point Datatypen: real und double-precision.

precision ist definiert als: maximum number of digits to the left and right of the decimal point

Gemäss postgres doc hat real max. eine precision von 6 decimal digits und double precision hat eine von max. 15 decimal digits.

Das heisst bspw. die Zahl 2.1357387654 müsste doch als 2.13574 angezeigt werden, oder? 1 Stelle vor dem Dezimalpunkt und 5 danach, macht total 6.

Habe es gerade ausprobiert mit einer Beispieltabelle in pgAdmin:

CREATE TABLE number_data_types (
numeric_column numeric(20,5),
real_column real,
double_column double precision
);

INSERT INTO number_data_types
VALUES
(.7, .7, .7),
(2.13579, 2.13579, 2.13579),
(2.1357387654, 2.1357387654, 2.1357387654);

SELECT * FROM number_data_types;

In der Spalte real_column und der letzten Zeile wird bei mir die Zahl 2.1357388 dargestellt…

Warum??? Kann doch nicht sein, dass bei mir für real eine andere precision eingestellt ist?

Die Dezimaltypen werden ja intern auf Byteblöcke gemapt. Die Precision und Scale Angaben in der Tabellendeklaration kann man (auch Plattform abhängig> Bitbreite) daher wohl eher als grobe Angaben verstehen.
Aus der Doku

On all currently supported platforms, the real type has a range of around 1E-37 to 1E+37 with a precision of at least 6 decimal digits
Der entscheidende Punkt ist hier demnach "at least 6. Es kann also auch mehr sein, implementierungs- und plattformabhängig.

Evtl. geht es Dir aber auch gar nicht um die Genauigkeit des Wertes, sondern um die reine Anzeige. Die musst Du bei Bedarf sowieso durch Formatfunktionen oder Rundungsoperationen herstellen.
Ist es umgekehrt, musst Du Dir genau überlegen, wieviel signifikante Stellen in den Typen abgelegt werden sollen und ob es geeignete Typen sind. Dass die Typen nicht zwingend reproduzierbare Werte in Nachkommastelle xy liefern, ist ebenfalls in der Doku erklärt.

1 „Gefällt mir“

real und double sind Datentypen die immer nur “ungefähr” den Wert speichern der angegeben wird. Nicht jede Zahl ist verlustfrei auf real oder double abbildbar. Deswegen kann es sein, dass Du einen anderen Wert zurückbekommst, als Du speicherst. Das liegt in der Natur der Sache. Wenn Du Wert auf exakte Zahlen legst, dann musst Du numeric nehmen.

Mehr Details dazu hier: https://floating-point-gui.de/

Des weiteren gibt es dann auch noch einen Unterschied zwischen dem gespeicherten Wert und den Wert die der SQL client anzeigt - dort findet ja auch nochmal eine Formatierung und evtl. Rundung für die Anzeige statt.

1 „Gefällt mir“