数值精度和对数

Bea*_*eld 1 floating-point logarithm r

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

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
Run Code Online (Sandbox Code Playgroud)

但是,我本来期望结果是近似的 0.5,因为我预计两种情况下的基数大约是 1.00004:

logb( x[2], 1.00004 ) - logb( x[1], 1.00004 )
# [1] 0.500005
Run Code Online (Sandbox Code Playgroud)

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

编辑

我实际上想做什么

我需要重新调整正数(a, b) -> (a',b')b > a,这样两个数字对新的规模差异d'( a', b' ) = b' - a'较大1当且仅当原来的规模差异d(a, b) = b -[ a + ( a * ppm * 1E-6) + (mDa * 1E-3)]较大为零.我知道可能有问题,因为d(a, b) ? d(b, a).对于值的典型范围是a,b ? [50, 1500],mDa ? [0, 10]ppm ? [1, 50].

jos*_*ber 8

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

logb(100, 1.0000399996)
# 115132.7
logb(100, 1.00004)
# 115131.6
logb(100, 1.0000400004)
# 115130.4
Run Code Online (Sandbox Code Playgroud)


Car*_*oft 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
Run Code Online (Sandbox Code Playgroud)

从而表明josilber的答案是正确的.