我遇到问题(至少我认为我有问题),计算如下:
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]
。
答案 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