从数学上讲,其中一个数字将是 appx。零,另一个。您的数字之间的差异很大,所以我什至想知道这是否有意义。
但是一般来说,要做到这一点,您可以使用logspace_add
R 引擎盖下的 C 函数中的想法。可以定义logxpy ( =log(x+y) )
whenlx = log(x)
和ly = log(y)
as :
logxpy <- function(lx,ly) max(lx,ly) + log1p(exp(-abs(lx-ly)))
这意味着我们可以使用:
> la1 <- 1000*log(0.1)
> la2 <- 1200*log(0.2)
> exp(la1 - logxpy(la1,la2))
[1] 5.807714e-162
> exp(la2 - logxpy(la1,la2))
[1] 1
如果您有更多数字,也可以递归调用此函数。请注意,1 仍然是 1,而不是 1 minus 5.807...e-162
。如果您确实需要更高的精度并且您的平台支持 long double 类型,您可以使用例如 C 或 C++ 编写所有代码,然后稍后返回结果。但如果我是对的,R 可以——目前——只处理正常的双打,所以当结果显示时,你最终会再次失去精度。
编辑 :
为你做数学:
log(x+y) = log(exp(lx)+exp(ly))
= log( exp(lx) * (1 + exp(ly-lx) )
= lx + log ( 1 + exp(ly - lx) )
现在你只取最大的 lx,然后你得到表达式logxpy()
。
编辑2:为什么要取最大值呢?很简单,确保您在 exp(lx-ly) 中使用负数。如果 lx-ly 变得太大,则 exp(lx-ly) 将返回 Inf。这不是一个正确的结果。exp(ly-lx) 将返回 0,从而获得更好的结果:
说 lx=1 和 ly=1000,然后:
> 1+log1p(exp(1000-1))
[1] Inf
> 1000+log1p(exp(1-1000))
[1] 1000