数值精度和对数

时间:2014-01-22 16:08:02

标签: r floating-point logarithm

我遇到问题(至少我认为我有问题),计算如下:

ppm <- 20
mDa <- 2
x <- c( 100, 100.002 )

base  <- 1 + ((x * ppm * 1E-6) + (mDa * 1E-3))/x
base
# [1] 1.00004 1.00004
base - 1.00004
# [1]  0.00000e+00 -3.99992e-10

logb( x[2], base[2] ) - logb( x[1], base[1] )
# [1] 1.651291

但是,我希望结果是大约 0.5,因为我预计在两种情况下基数都大约 {{1 }}:

1.00004

虽然我手头没有证据,但我怀疑logb( x[2], 1.00004 ) - logb( x[1], 1.00004 ) # [1] 0.500005 的结果在数学上是否正确,我认为我遇到了数值精度问题。任何想法如何避免这个问题都非常感谢。

修改

我实际上在做什么

我需要使用logb( x[2], 1.00004 ) - logb( x[1], 1.00004 )重新调整正数(a, b) -> (a',b'),以便新标度b > a上两个数字的差异大于1,如果原始标度上的差异{{1更大的零。我知道可能存在问题,因为d'( a', b' ) = b' - a'。值的典型范围是d(a, b) = b -[ a + ( a * ppm * 1E-6) + (mDa * 1E-3)]d(a, b) ≠ d(b, a)a,b ∈ [50, 1500]

3 个答案:

答案 0 :(得分:8)

当您使用基数非常接近1的大数字对数时,该基数的微小差异可能导致最终值的显着差异。你的基数相差0.0000000004,但这可以与非常接近1的基数产生差异:

logb(100, 1.0000399996)
# 115132.7
logb(100, 1.00004)
# 115131.6
logb(100, 1.0000400004)
# 115130.4

答案 1 :(得分:5)

尝试Rmpfr

Rgames> rfoo<-mpfr(100,100)
Rgames> log100<-log(rfoo)
Rgames> log100
1 'mpfr' number of precision  100   bits 
[1] 4.6051701859880913680359829093676
Rgames> logbase<-log(mpfr(1.0004,100))
Rgames> log100/logbase
1 'mpfr' number of precision  100   bits 
[1] 11515.227896589510924644721707849
Rgames> logbase<-log(mpfr(1.00004,100))
Rgames> log100/logbase
1 'mpfr' number of precision  100   bits 
[1] 115131.55721932987847380223102368

因此显示了josilber的回答是正确的。

答案 2 :(得分:0)

@josiber是对的,log(1.00004)约为0.00004所以你除以一个很小的数字并得到巨大的结果......所以你观察到的差异相对较小。

如果您在没有扩展精度库的情况下寻求更高的准确度,您也可以尝试使用计算log1p(x)的{​​{1}}

log(1+x)

然后

baseM1  <- ((x * ppm * 1E-6) + (mDa * 1E-3))/x