2017-05-31 51 views
1

我为累积二项式分布创建了一个函数。它适用于非常适中的样本量,但是在较大的样本中会出现算术溢出。SQL二项式分布/算术溢出

Binomial Distribution

最大的罪魁祸首是n!在Excel 170中! = 7.3E + 306。 171! = #NUM!

Excel有计算二项式分布的内部函数,并将其与NS的作品不多,比170

大得多有什么我能做的生成#分别的大小限制?

编辑:我打这个

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],@n-[email protected]) 

     SET @i = @i+1 




    END 

    RETURN @probout 
END 

回答

2

让我给你一个提示。

如果计算完整阶乘因子,您很快就会发生溢出。如果你做增量计算,你不会。例如,不是将(5 // 3)计算为(5 * 4 * 3 * 2 * 1)/((3 * 2)*(3 * 2 * 1)),而是将其计算为:(其中, 5/3)*(4/2)*(3/3)*(2/2)*(1/1)。 。 。哦,等等,你可以看到最后三个词都是“1”。

需要明确的是,你要计算的产品:

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

对于我0和k之间 - 1。也就是说,你将ķ连续编号的ñ结束的产品k从1开始的连续数字。

您会看到这种增量方法将防止溢出问题。

+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 ^大* 0.5 ^大。 所以我认为我需要在循环的那部分中加入功率条件...... –

+0

@ T.Hannah。 。 。是的,非常真实。我专注于等式的“选择”部分。 –