2016-01-26 58 views
0

我想知道如何计算R中的大数值乘法。 R返回Inf!R中的大数乘法

例如:

6.350218e+277*2.218789e+215 
[1] Inf 

让我澄清一下这个问题更多: 考虑下面的代码和outFunc函数的结果:

library(hypergeo) 
poch <-function(a,b) gamma(a+b)/gamma(a) 
n<-c(37 , 41 , 4 , 9 , 12 , 13 , 2 , 5 , 23 , 73 , 129 , 22 , 121) 
v<-c(90.2, 199.3, 61, 38, 176.3, 293.6, 318.6, 328.7, 328.1, 313.3, 142.4, 92.9, 95.5) 
DF<-data.frame(n,v) 


outFunc<-function(k,w,r,lam,a,b) { 
    ((((w*lam)^k) * poch(r,k) * poch(a,b)) * hypergeo(r+k,a+k,a+b+k,-(w*lam)))/(poch(a+k,b)*factorial(k)) 

} 

,并在函数返回:

outFunc(DF$n,DF$v,0.2, 1, 3, 1) 
[1] 0.002911330+ 0i 0.003047594+ 0i 0.029886646+ 0i 0.013560599+ 0i 0.010160073+ 0i 
[6] 0.008928524+ 0i 0.040165795+ 0i 0.019402318+ 0i 0.005336008+ 0i 0.001689114+ 0i 
[11]   Inf+NaNi 0.005577985+ 0i   Inf+NaNi 

从上面可以看出,outFunc返回Inf + NaNi for nv我检查了部分代码段,我发现这些n值返回的结果poch(r,k)是Inf。(w lam)^ k poch(r,k)我还检查我的代码在数学等效代码这一切都OK了:

in: out[indata[[All, 1]], indata[[All, 2]], 0.2, 1, 3, 1] 

out: {0.00291133, 0.00304759, 0.0298866, 0.0135606, 0.0101601, 0.00892852, \ 
     0.0401658, 0.0194023, 0.00533601, 0.00168911, 0.000506457, \ 
     0.00557798, 0.000365445} 

现在请让我知道如何解决这个问题,因为简单,因为它是在数学。问候。你必须在基础R,它不需要专门的库中可用

+2

尝试'GMP :: mul.bigz(6.350218e + 277,+ 2.218789e 215)' – Khashaa

+0

或用[大人国(https://cran.r-project.org/web/ packages/Brobdingnag/index.html)库 –

+0

感谢Khashaa 2,但它返回:错误mul.bigz(6.350218e + 277 * 2.218789e + 215): 参数“e2”丢失,没有默认 –

回答

4

对于第一,我建议两个有用的记载:logarithmshow floating values are handled by a computer。这些都是相关的,因为用一些“技巧”你可以处理比你想象的更大的价值。例如,您对poch函数的定义非常糟糕。这是因为分数可以被简化很多,但计算机会首先评估分子,如果它溢出,结果将是无用的。这就是为什么R提供旁边gammalgamma功能:它只是计算gamma的对数,可以处理更大的值。因此,我们计算您的函数中每个因子的log,然后我们使用exp来恢复预期值。试试这个:

#redefine poch properly 
poch<-function(a,b) lgamma(a+b) - lgamma(a) 
#redefine outFunc 
outFunc<-function(k,w,r,lam,a,b) { 
    exp((k*(log(w)+log(lam))+ poch(r,k) + poch(a,b)) + 
    log(hypergeo(r+k,a+k,a+b+k,-(w*lam)))- poch(a+k,b)-lgamma(k+1)) 
} 
#Now we go 
outFunc(DF$n,DF$v,0.2, 1, 3, 1) 
#[1] 0.0029113299+0i 0.0030475939+0i 0.0298866458+0i 0.0135605995+0i 
#[5] 0.0101600732+0i 0.0089285243+0i 0.0401657947+0i 0.0194023182+0i 
#[9] 0.0053360084+0i 0.0016891144+0i 0.0005064566+0i 0.0055779850+0i 
#[13] 0.0003654449+0i 
+2

还有'lfactorial'。 – Roland

+0

@Roland是的,当然,因为'factorial'只是'gamma'(和'lgamma'的'lfactorial')的包装。 – nicola

+0

非常感谢nicola,现在需要更多的新方程式。 –

6

一种选择,是将两个数字转换为一个共同的基础,然后添加指数合力得到最终结果:

> x <- log(6.350218e+277, 10) 
> x 
[1] 277.8028 
> y <- log(2.218789e+215, 10) 
> y 
[1] 215.3461 
> x + y 
[1] 493.1489 

由于10^x * 10^y = 10^(x+y),您的最终答案是10^493.1489

请注意,此解决方案不允许实际存储R将通常视为INF的数字。因此,在这个例子中,你仍然不能计算10^493,但你可以梳理出产品。

+1

也许值得指出的是,浮点精确度起着一定的作用,但通常与此数量级无关 – Roland

+0

从我童年时代起,无限加上一个仍然是无穷大:-) –

+0

亲爱的Tim Biegeleisen,但R中10^493.1489的结果仍然是Inf并且有问题没有解决!!!!!! –

4
> library(gmp) 
> x<- pow.bigz(6.350218,277) 
> y<- pow.bigz(2.218789,215) 
> x*y 

Big Integer ('bigz') : 
[1] 18592826814872791919942226542714580401488894909642693257011204682802122918146288728149155739011270579948954646130492024596687919148494136290260248656581476275790189359808616520170359345612068099238508437236172770752199936303947098513476300142414338199993261924467166943683593371648