2

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

この問題が発生する理由と、この種の問題の解決策を教えてください。

4

2 に答える 2

6

あなたの最初の問題は、出力タイプがexp()入力タイプと同じであることが原因だと思います。整数値を使用しているため、結果が整数に収まらないと不平を言っています。

それが、浮動小数点型の範囲がより広い理由exp(5999.1)であり、おそらく機能する理由です。exp(5999.0)

2 番目のエラーは少し異なります。計算中のオーバーフローではなく、入力引数が大きすぎるという事実を訴えています。どこかで入力の健全性チェックが行われている可能性があります。

浮動小数点値でさえ、最終的には範囲外になります。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 は大きすぎますPOWER()が、10000 は問題ありません:D Postgres はの引数の小数点を好まないようです。申し訳ありませんが、それを修正することはできません。

1 つの解決策は、power と write の算術プロパティを使用することPOWER(POWER(EXP(1::NUMERIC), n*10), 0.1)ですが、その値の組み合わせは Postgres の power の実装にはまだ大きすぎます。あなたの戦いで頑張ってください。

于 2012-08-17T08:48:56.613 に答える