2016-02-12 102 views
0

有誰知道如何解決Postgres中的以下錯誤?錯誤:值超出範圍:下溢

ERROR: value out of range: underflow CONTEXT: PL/pgSQL function pgnumerics.poisspdf(double precision,double precision) line 1 at assignment PL/pgSQL function pgnumerics.poisscdf(double precision,double precision) line 1 at assignment ********** Error **********

ERROR: value out of range: underflow SQL state: 22003 Context: PL/pgSQL function pgnumerics.poisspdf(double precision,double precision) line 1 at assignment PL/pgSQL function pgnumerics.poisscdf(double precision,double precision) line 1 at assignment

pgnumerics.poisscdf(dp,dp)函數一直運行到我的數據的第5300行左右。我無法確定是什麼導致了下溢。

pgnumerics.poisscdf((qoh),(add * replen_days)) 

下面是poisscdf()

-- Function: pgnumerics.poisscdf(double precision, double precision) 

-- DROP FUNCTION pgnumerics.poisscdf(double precision, double precision); 

CREATE OR REPLACE FUNCTION pgnumerics.poisscdf(
    x double precision, 
    lambda double precision) 
    RETURNS double precision AS 
$BODY$ DECLARE y double precision; 
i integer;BEGIN y:=0.0;FOR i IN 0..X LOOP y:=y+pgnumerics.poisspdf(i,LAMBDA);END LOOP;RETURN y;END;$BODY$ 
    LANGUAGE plpgsql VOLATILE 

該函數調用的代碼:pgnumerics.poisspdf() - 功能:pgnumerics.poisspdf(雙精度,雙精度)

- DROP FUNCTION pgnumerics.poisspdf(雙精度,雙精度);

CREATE OR REPLACE FUNCTION pgnumerics.poisspdf(
    x double precision, 
    lambda double precision) 
    RETURNS double precision AS 
$BODY$ DECLARE y double precision;BEGIN y:=exp(-LAMBDA+X*ln(LAMBDA)-pgnumerics.gammaln(X+ 
1.0));RETURN y;END;$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 

其中要求pgnumerics.gammaln()

-- Function: pgnumerics.gammaln(double precision) 

-- DROP FUNCTION pgnumerics.gammaln(double precision); 

CREATE OR REPLACE FUNCTION pgnumerics.gammaln(x double precision) 
    RETURNS double precision AS 
$BODY$ DECLARE y double precision;xnum double precision;xden double precision;xm1 double precision;r double precision;xx double precision;i int; 
BEGIN xnum:=0.0;xden:=1.0;y:=x;if x<=(1E-10) then y:=-1.0*ln(x);elsif x<=0.5 then xnum:=xnum*y+4.945235359296727046734888e0;xnum:=xnum*y+2.018112620856775083915565e2;xnum:=xnum*y+2.290838373831346393026739e3;xnum:=xnum*y+1.131967205903380828685045e4;xnum:=xnum*y+2.855724635671635335736389e4;xnum:=xnum*y+3.848496228443793359990269e4;xnum:=xnum*y+2.637748787624195437963534e4;xnum:=xnum*y+7.225813979700288197698961e3;xden:=xden*y+6.748212550303777196073036e1;xden:=xden*y+1.113332393857199323513008e3;xden:=xden*y+7.738757056935398733233834e3;xden:=xden*y+2.763987074403340708898585e4;xden:=xden*y+5.499310206226157329794414e4;xden:=xden*y+6.161122180066002127833352e4;xden:=xden*y+3.635127591501940507276287e4;xden:=xden*y+8.785536302431013170870835e3;y:=-ln(y)+(y*(-5.772156649015328605195174e-1+y*(xnum/xden)));elsif x<=0.6796875 then xm1:=(x-0.5)-0.5;xnum:=xnum*xm1+4.974607845568932035012064e0;xnum:=xnum*xm1+5.424138599891070494101986e2;xnum:=xnum*xm1+1.550693864978364947665077e4;xnum:=xnum 
*xm1+1.847932904445632425417223e5;xnum:=xnum*xm1+1.088204769468828767498470e6;xnum:=xnum*xm1+3.338152967987029735917223e6;xnum:=xnum*xm1+5.106661678927352456275255e6;xnum:=xnum*xm1+3.074109054850539556250927e6;xden:=xden*xm1+1.830328399370592604055942e2;xden:=xden*xm1+7.765049321445005871323047e3;xden:=xden*xm1+1.331903827966074194402448e5;xden:=xden*xm1+1.136705821321969608938755e6;xden:=xden*xm1+5.267964117437946917577538e6;xden:=xden*xm1+1.346701454311101692290052e7;xden:=xden*xm1+1.782736530353274213975932e7;xden:=xden*xm1+9.533095591844353613395747e6;y:=-ln(y)+(xm1*(4.227843350984671393993777e-1+xm1*(xnum/xden)));elsif x<=1.5 then xm1:=(x-0.5)-0.5;xnum:=xnum*xm1+4.945235359296727046734888e0;xnum:=xnum*xm1+2.018112620856775083915565e2;xnum:=xnum*xm1+2.290838373831346393026739e3;xnum:=xnum*xm1+1.131967205903380828685045e4;xnum:=xnum*xm1+2.855724635671635335736389e4;xnum:=xnum*xm1+3.848496228443793359990269e4;xnum:=xnum*xm1+2.637748787624195437963534e4;xnum:=xnum*xm1+ 
7.225813979700288197698961e3;xden:=xden*xm1+6.748212550303777196073036e1;xden:=xden*xm1+1.113332393857199323513008e3;xden:=xden*xm1+7.738757056935398733233834e3;xden:=xden*xm1+2.763987074403340708898585e4;xden:=xden*xm1+5.499310206226157329794414e4;xden:=xden*xm1+6.161122180066002127833352e4;xden:=xden*xm1+3.635127591501940507276287e4;xden:=xden*xm1+8.785536302431013170870835e3;y:=xm1*(-5.772156649015328605195174e-1+xm1*(xnum/xden));elsif x<=4.0 then xm1:=x-2.0;xnum:=xnum*xm1+4.974607845568932035012064e0;xnum:=xnum*xm1+5.424138599891070494101986e2;xnum:=xnum*xm1+1.550693864978364947665077e4;xnum:=xnum*xm1+1.847932904445632425417223e5;xnum:=xnum*xm1+1.088204769468828767498470e6;xnum:=xnum*xm1+3.338152967987029735917223e6;xnum:=xnum*xm1+5.106661678927352456275255e6;xnum:=xnum*xm1+3.074109054850539556250927e6;xden:=xden*xm1+1.830328399370592604055942e2;xden:=xden*xm1+7.765049321445005871323047e3;xden:=xden*xm1+1.331903827966074194402448e5;xden:=xden*xm1+1.136705821321969608938755e6;xden 
:=xden*xm1+5.267964117437946917577538e6;xden:=xden*xm1+1.346701454311101692290052e7;xden:=xden*xm1+1.782736530353274213975932e7;xden:=xden*xm1+9.533095591844353613395747e6;y:=xm1*(4.227843350984671393993777e-1+xm1*(xnum/xden));elsif x<=12.0 then xm1:=x-4.0;xden:=-1.0;xnum:=xnum*xm1+1.474502166059939948905062e4;xnum:=xnum*xm1+2.426813369486704502836312e6;xnum:=xnum*xm1+1.214755574045093227939592e8;xnum:=xnum*xm1+2.663432449630976949898078e9;xnum:=xnum*xm1+2.940378956634553899906876e10;xnum:=xnum*xm1+1.702665737765398868392998e11;xnum:=xnum*xm1+4.926125793377430887588120e11;xnum:=xnum*xm1+5.606251856223951465078242e11;xden:=xden*xm1+2.690530175870899333379843e3;xden:=xden*xm1+6.393885654300092398984238e5;xden:=xden*xm1+4.135599930241388052042842e7;xden:=xden*xm1+1.120872109616147941376570e9;xden:=xden*xm1+1.488613728678813811542398e10;xden:=xden*xm1+1.016803586272438228077304e11;xden:=xden*xm1+3.417476345507377132798597e11;xden:=xden*xm1+4.463158187419713286462081e11;y:= 
1.791759469228055000094023e0+xm1*(xnum/xden);else r:=5.7083835261e-03;xm1:=ln(y);xx:=x*x;r:=r/xx-1.910444077728e-03;r:=r/xx+8.4171387781295e-04;r:=r/xx-5.952379913043012e-04;r:=r/xx+7.93650793500350248e-04;r:=r/xx-2.777777777777681622553e-03;r:=r/xx+8.333333333333333331554247e-02;r:=r/y;y:=r+0.9189385332046727417803297-0.5*xm1+y*(xm1-1);end if;return y;END;$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 

行的錯誤出第一是這個數據輸入:

Select pgnumerics.poisscdf(242, (0.0153846153846154 + 10)) 

任何幫助表示讚賞!

回答

0

要解決此錯誤,我使用正態分佈模型來計算x值。這讓我進入了Poisson分佈的球場,消除了下溢問題。這種情況允許尋求目標。如果您需要使用真實數據,解決方案將無法正常工作。我用其他幾種方式操縱輸入;但是,這似乎是這種情況下最可持續的方法。

計算正態分佈的x值:

X = Round((Avg_demand) + (Stddev * Service_factor)) as normal_distribution_target_qty