postgresql中的指数问题

时间:2012-08-17 05:51:20

标签: database postgresql postgresql-9.1 postgresql-9.0

我在postgresql中面临指数函数的问题。如果我使用这个select语句select exp(5999),我得到:

ERROR: value out of range: overflow 
SQL state: 22003

如果我使用这个select语句select exp(5999.1),我会得到指数结果。

在其他情况下,如果我使用此语句select exp(9999.1),我收到以下错误:

ERROR: argument for function "exp" too big
SQL state: 22003

请让我知道为什么会出现这个问题以及这类问题的解决方案是什么?

2 个答案:

答案 0 :(得分:5)

我认为您的第一个问题是由exp()的输出类型与输入类型相同的事实引起的。因为你使用了一个整数值,所以它抱怨结果不适合整数。

这可能是exp(5999.1),可能exp(5999.0)工作的原因,浮点类型的范围更大。

你的第二个错误略有不同,它抱怨计算过程中没有溢出,但是输入参数太大了。它可能在某处对输入进行了一些完整性检查。

即使浮点值最终超出范围。 e 9999 大约10 4300 ,这是一个相当大的数字,可能远远超出您在数据库应用程序中看到的内容。

事实上,我对数据库应用程序中如此大数字的用例感兴趣。这听起来更适合像MPIR这样的bignum包。

答案 1 :(得分:1)

如果传递INTEGER参数,exp()函数将尝试返回double precision值。在n = 709的上方,它将达到64位浮点数(约10 ^ 308)的极限,并且无法计算e ^ n。解决方案是使用NUMERIC类型:

传递您的参数
SELECT EXP(710); -- failure!
SELECT EXP(710::NUMERIC); -- OK
SELECT EXP(5999.1::NUMERIC); -- huge but OK

EDIT!

至于 ERROR:函数的参数“exp”太大的SQL状态:22003 。我试着写一个解决方法。跑吧:

SELECT n, POWER(EXP(1::NUMERIC), n) FROM (VALUES(9998), (9999), (10000)) AS foo (n)

它会起作用。但是然后将9999改为9999.1,你将再次得到那个愚蠢的错误。这是荒唐的! 9999.1 太大但10000很好:D看起来Postgres不喜欢POWER()的参数中的小数点。对不起,我无法解决这个问题。

一种解决方案是使用幂的算术属性并写POWER(POWER(EXP(1::NUMERIC), n*10), 0.1),但该值组合对于Postgres的权力实现来说仍然太大。祝你好运。