我非常熟悉IEEE 754单精度和双精度数据类型如何得到它们的支持。我已经阅读过关于每个计算机科学家应该知道浮点运算的文章,但我对Postgresql的选择感到困惑。
我创建了一个表
create table ttt(f4 float4, f8 float8, fn numeric);
我添加了一些值:
insert into ttt (f4,f8,fn) values(12.206,12.206,12.206);
我查询:
select count(*) from ttt where f4=12.206;
count
-------
0
(1 row)
我要求解释:
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)
因此查询尝试匹配double precsion版本 12.206的值作为单个precsion存储的值,而它们不是 匹配,这并不奇怪。
令我惊讶的是,默认情况下是postgresql 似乎将数字视为数字:
gsh=# select 12.206;
?column?
----------
12.206
(1 row)
gsh=# select pg_typeof(12.206);
pg_typeof
-----------
numeric
(1 row)
如果默认情况下将数字视为数字,为什么不进行过滤比较 反对12.206作为数字而不是双精度?我发现这是违反意外的。
有什么想法吗?
答案 0 :(得分:1)
可以使用type resolution rules for operators解释这一点。
正如您所看到的,表达式中=
运算符左侧的类型为real
,右侧的类型为numeric
。
从numeric
到double precision
和real
以及从real
到double precision
的隐式演员表(请在{\dCS
中查看} {1}})。
如果您检查可用的psql
运算符(请在=
中查看“\doS =
”),您会在步骤3.a之后找到该运算符。以下运营商仍然存在:
psql
在步骤3.c.中,选择第一个运算符,因为它与左输入类型完全匹配。
您可以使用real = double precision
double precision = double precision
常量强制使用real = real
运算符,例如
real
或
... WHERE f4 = 12.206::real