比方说,我想在SQL中以任意十进制精度查看数字结果。考虑下面的SQL,该SQL产生黄金平均值(一个非常不合理的数字,该数字有很多小数位):
postgres=# SELECT (1 + SQRT(5)) / 2 AS golden_mean;
golden_mean
------------------
1.61803398874989
(1 row)
但是至少在psql
中,此结果被截断为14个小数位。起初我认为这是因为sqrt
函数中的默认强制转换为double precision
:
postgres=# SELECT pg_typeof((1 + SQRT(5)) / 2);
pg_typeof
------------------
double precision
(1 row)
但是,将输入(以及输出)强制转换为NUMERIC
仍会显示截断(尽管这次是15 DP):
postgres=# SELECT (1 + SQRT(5::NUMERIC)) / 2 AS golden_mean;
golden_mean
--------------------
1.6180339887498950
(1 row)
这对我来说很奇怪,根据the spec,NUMERIC
应该可以存储:
小数点前最多131072位数字;小数点后最多16383位数字
此外,
注:在类型声明中明确指定的最大允许精度为1000;没有指定精度的NUMERIC受表8-2中所述的限制。
但是,情况似乎并非如此,结果被截断了。我当然可以指定精度/小数位数,但这只能让我获得999个小数位:
postgres=# SELECT (1 + SQRT(5::NUMERIC(1000,999))) / 2 AS golden_mean;
golden_mean
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137484754088075386891752126633862223536931793180060766726354433389086595939582905638322661319928290267880675208766892501711696207032221043216269548626296313614438149758701220340805887954454749246185695364864449241044320771344947049565846788509874339442212544877066478091588460749988712400765217057517978834166256249407589069704000281210427621771117778053153171410117046665991466979873176135600670874807101317952368942752194843530567830022878569978297783478458782289110976250030269615617002504643382437764861028383126833037242926752631165339247316711121158818638513316203840052221657912866752946549068113171599343235973494985090409476213222981017261070596116456299098162905552085247903524060201727997471753427775927786256194320827505131218156285512224809394712341451702237358057727861600868838295230459264787801788992199027077690389532196819861514378031499741106926088674296226757560523172777520353613936
(1 row)
我认为这可能是因为实际上 存储了所需的精度,但是psql
放弃了精度,但事实并非如此。如果尝试在计算后 进行强制转换,则只获得原始的15 DP舍入:
postgres=# SELECT ((1 + SQRT(5)) / 2)::NUMERIC(1000,999) AS golden_mean;
golden_mean
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.618033988749890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
(1 row)
postgres=#
那么,有什么方法可以指定此计算方式,以便我能够看到完整的表示形式到任意小数位,并且仅受实现限制(即16383 DP)的约束吗?或者,在另一种措辞中–我可以查询黄金中位数的第N
位是什么(1000 < N < 16383
在哪里)?还是这仅仅是Postgres sqrt
函数的局限性(在这里(可能出于性能原因),他们已将默认返回类型指定为NUMERIC
而不是NUMERIC(16,16)
?
答案 0 :(得分:1)
您仅将 some 个值转换为所需的精度。如果希望整体计算保持该精度,则必须至少确保所有输入都具有该精度。
默认情况下,1
不具有您描述的精度。因此,您需要将该值以及计算中包含的所有其他数字转换为具有所需精度的类型。
SELECT
(1::NUMERIC(1000, 999) + SQRT(5::NUMERIC(1000, 999))) / 2::NUMERIC(1000, 999)
AS golden_mean;