2

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

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

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

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

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

请让我知道为什么会发生此问题以及此类问题的解决方案是什么?

4

2 回答 2

6

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

这可能是浮点类型具有更大范围的原因exp(5999.1),并且可能有效。exp(5999.0)

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

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

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

于 2012-08-17T05:55:41.680 回答
2

如果您传递一个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

编辑!

至于ERROR: argument for function "exp" too big SQL state: 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 和 write 的算术属性,POWER(POWER(EXP(1::NUMERIC), n*10), 0.1)但是对于 Postgres 的 power 实现来说,值组合仍然太大。祝你战斗顺利。

于 2012-08-17T08:48:56.613 回答