2017-05-31 16 views
1

累積二項分布の関数を作成しました。非常に控えめなサンプルサイズでうまく動作しますが、大きなサンプルでは算術オーバーフローが発生します。SQLの二項分布/算術オーバーフロー

Binomial Distribution

最大の原因は、Nであります! 170でエクセル! = 7.3E + 306。 171! = #NUM!

Excelは、二項分布を算出し、内部の機能を有しており、それは私が#Sの大きさは、生成を制限するために行うことができるものがあります170

よりもはるかに大きく、多くのNSで動作しますか?

編集:私はこの

SET @probout = 2*3*4*5*6*7*8*9*10*11*12 

と共演は、以下のオーバーフロー

機能が生じた細かい

SET @probout = 2*3*4*5*6*7*8*9*10*11*12*13/10000 

働きました。

ALTER FUNCTION [dbo].[binomdist_cumulative] 
    ( 
    @n  int 
    ,@k  int 
    ,@p  float 
    ) 
RETURNS float 
AS 
BEGIN 

    -- Local Variable Declarations 
    -- --------------------------- 
    DECLARE   @kfac   float 
        ,@nfac   float 
        ,@nkfac   float 
        ,@i    float 
        ,@f    int 
        ,@probout  float 

    SET @i = 0 
    SET @f = 0 
    SET @nfac = 0 
    SET @kfac = 0 
    SET @nkfac = 0 
    SET @probout = 0 

    WHILE @i <= @k 
    BEGIN 


--k! 
     SET @f = @i-1 
     SET @kfac = @i 
     IF @kfac > 0 
     BEGIN 
      WHILE @f > 0 
      BEGIN 
       SET @kfac = @kfac*@f 
       SET @f = @f -1 
      END 
     END 
     ELSE 
     BEGIN 
      SET @kfac = 1 
     END 

--n! 
     SET @f = @n-1 
     SET @nfac = @n 
     IF @nfac > 0 
     BEGIN 
      WHILE @f > 0 
      BEGIN 
       SET @nfac = @nfac * @f 
       SET @f = @f -1 
      END 
     END 
     ELSE 
     BEGIN 
      SET @nfac = 1 
     END 

--(n-k)! 
     SET @f = @[email protected] 
     SET @nkfac = @[email protected] 
     IF @nkfac > 0 
     BEGIN 
      WHILE @f > 0 
      BEGIN 
       SET @nkfac = @nkfac * @f 
       SET @f = @f -1 
      END 
     END 
     ELSE 
     BEGIN 
      SET @nkfac = 1 
     END 

--Accumulate distribution 
     SET @probout = @probout + @nfac/(@kfac*@nkfac)*POWER(@p,@i)*POWER([email protected],@[email protected]) 

     SET @i = @i+1 




    END 

    RETURN @probout 
END 

答えて

2

ヒントを教えてください。あなたは完全な階乗を計算する場合

、あなたはすぐにオーバーフローを得ようとしています。増分計算を行うと、あなたは増分計算を行いません。

たとえば、(5 * 3 * 2 * 1)/((3 * 2)*(3 * 2 * 1))として(5 // 3)を計算する代わりに、 5/3)×(4/2)×(3/3)×(2/2)×(1/1) 。 。ああ、待って、あなたは最後の3つの用語はすべて "1"であることがわかります。

は明確にするために、あなたはの積を計算します:0とkの間、私のために

((n - i)/(n - k - i) 

を - 1です、あなたはのnで終わるK連続した番号の製品を分割していますkから始まる連続番号です。

このような漸進的なアプローチでは、オーバーフローの問題を未然に防ぐことができます。

+0

ありがとうございます!私は数学はやや離れていると思っていますが、私はそのアプローチを理解しています。 –

+0

私が間違っていない限り、これにはスケール制限があり、悪くないとは考えていません。 7/4の例を挙げる。基本的に(7 * 6 * 5 * 4 * 3 * 2 * 1)/(4 * 3 * 2 * 1 * 3 * 2 * 1)です。 は、私は可能な最大の分母を使用して7月4日* 6月3日* 5月3日* 4月2日* 3月2日* 2月1日* 1月1日やってループを書きました。 大きな数字では、本質的に2 ^の大きな数字で巨大な数字になります。これには最終的に0.5^big * 0.5^bigが乗算されます。 だから私はT.Hannah @ –

+0

...私も、ループの部分にパワー条件を組み込むことが必要だと思います。 。 。はい、本当です。私は方程式の「選択」部分に焦点を合わせました。 –

関連する問題