2017-04-13 6 views
3

Ich bin ziemlich vertraut damit, wie die IEEE 754 Single Precision und Double Precisions Datentypen ihre Überlegenheit haben. Ich habe die Artikel darüber gelesen, was jeder Informatiker über Gleitkommaarithmetik wissen sollte, aber ich bin verwirrt über eine Entscheidung, die Postgresql trifft.Was bestimmt den Datentyp, nach dem PostgreSQL gefiltert wird?

ich eine Tabelle

create table ttt(f4 float4, f8 float8, fn numeric); 

ich einige Werte hinzufügen:

insert into ttt (f4,f8,fn) values(12.206,12.206,12.206); 

Ich habe eine Abfrage:

select count(*) from ttt where f4=12.206; 
count 
------- 
    0 
(1 row) 

ich um eine Erklärung bitten:

gsh=# explain select count(*) from ttt where f4=12.206; 
         QUERY PLAN       
---------------------------------------------------------- 
Aggregate (cost=23.77..23.78 rows=1 width=0) 
    -> Seq Scan on ttt (cost=0.00..23.75 rows=6 width=0) 
     Filter: (f4 = 12.206::double precision) 
(3 rows) 

So versucht die Abfrage, die Doppelpräzisionsversion von 12.206 mit dem als Einzelpräzision gespeicherten Wert zu vergleichen, und sie sind nicht passend, was keine Überraschung ist.

Was mir eine Überraschung ist, dass standardmäßig postgresql seit scheinen Zahlen als numerisches zu behandeln:

gsh=# select 12.206; 
?column? 
---------- 
    12.206 
(1 row) 

gsh=# select pg_typeof(12.206); 
pg_typeof 
----------- 
numeric 
(1 row) 

Wenn Zahlen standardmäßig als numerisch behandelt werden, warum nicht die Filter gegen 12,206 Vergleichen als eine numerische anstelle einer doppelten Genauigkeit? Ich finde das eine Verletzung der geringsten Überraschung.

Irgendwelche Gedanken?

Antwort

1

Dies kann mit der type resolution rules for operators erklärt werden.

Wie Sie richtig feststellen, ist der Typ auf der linken Seite des Operators = in Ihrem Ausdruck real, und der Typ auf der rechten Seite ist numeric.

Es gibt implizite Abgüsse numeric-double precision und real und real-double precision (Check mit “ \dCS ” in psql). Wenn Sie die verfügbaren Operatoren = untersuchen (überprüfen Sie mit “ \doS = 10 in psql), finden Sie, dass nach Schritt 3.a. die folgenden Operatoren bleiben:

real    = double precision 
double precision = double precision 

In Schritt 3.c. wird die erste von dort Betreiber gewählt, weil es die linke Eingangstyp genau entspricht.

können Sie die Verwendung des real = real Betreiber zwingen, durch eine real Konstante verwendet, wie in

... WHERE f4 = 12.206::real 

oder

... WHERE f4 = REAL '12.206' 
Verwandte Themen