Ответ 1
Математически говоря, одним из этих чисел будет appx. ноль, а другой. Разница между вашими числами огромна, поэтому мне даже интересно, имеет ли это смысл.
Но для этого вы можете использовать идею из logspace_add
C-функции, которая находится под капотом R. Можно определить logxpy ( =log(x+y) )
, когда lx = log(x)
и ly = log(y)
как:
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 минус 5.807...e-162
. Если вам действительно нужна более высокая точность, и ваша платформа поддерживает длинные двойные типы, вы можете закодировать все, например, на 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