PostgreSQL 强大功能

问题描述 投票:0回答:1

根据 postgres 文档,哪里有两个

power
函数接口:

power ( a numeric, b numeric ) → numeric
power ( a double precision, b double precision ) → double precision

但是,当使用不同类型进行测试时,发生了一些奇怪的事情:

select ( power( (1 + 0.1689), (32/365.0) )) as power_base,                             -- 1.01377627781508836023 - numeric
       ( power( (1 + 0.1689) :: numeric(22,7)   , (32/365.0) :: double precision )) as power_num_dp,  -- 1.0137762778150883 - double precision
       ( power( (1 + 0.1689) :: double precision, (32/365.0) :: numeric(22,7)    )) as power_dp_num,  -- 1.0137762726135617 - double precision
       ( power( (1 + 0.1689) :: numeric(22,7)   , (32/365.0) :: numeric(22,7)    )) as power_num_num, -- 1.0137762726135616 - numeric
       ( power( (1 + 0.1689) :: double precision, (32/365.0) :: double precision )) as power_dp_dp,   -- 1.0137762778150883 - double precision

你可以看到 power_base 值中多了 4 位数字,但是

pg_typeof()
显示它是数字。另外,当将双精度与数字类型混合时 - power_dp_num 结果与 power_num_num 略有不同,我猜它可能是数字自动转换上 1.1689 的舍入误差。

所以我用PgAdmin和DBeaver在PG13和PG16中进行了测试,结果是相同的。

postgresql
1个回答
0
投票

没有发生任何奇怪的事情。分数

(32/365.0)
没有有限位数的精确表示;因此,使用不同的值进行计算。以下查询演示了类型转换导致的值差异:

SELECT
  (32 / 365.0::NUMERIC) AS num_value,
  (32 / 365.0::DOUBLE PRECISION) AS dp_value,
  (32 / 365.0::NUMERIC) - (32 / 365.0::DOUBLE PRECISION)::NUMERIC AS conversion_delta;
数值 dp_值 conversion_delta
0.08767123287671232877 0.08767123287671233 0.00000000000000002877

DOUBLE PRECISION
值不精确,精度约为 15 位十进制数字,而
NUMERIC
值小数点后最多可有 16363 位数字(请参阅 8.1. 数字类型)。混合
NUMERIC
DOUBLE PRECISION
值会导致隐式类型转换。

© www.soinside.com 2019 - 2024. All rights reserved.