首页 > 解决方案 > gnuplot:如何获得正确的数量级?

问题描述

这个问题/问题可能与这个主题有关。

如果您键入:

print log10(1e7)你会得到7.0

print int(log10(1e7))你会得到7

但是,如果您键入

print log10(1e6)你会得到6.0

print int(log10(1e6))你会得到5

这些可能是与相关的舍入误差,log10并且不能(?)避免。

因为如果你输入

print sprintf("%.20e",log10(1e6))5.99999999999999911182e+00

print sprintf("%.20e",log10(1e7))7.00000000000000000000e+00

您可以将其扩展和总结为一个情节:代码:

### power problem in gnuplot
reset session
set colorsequence classic
set key left
set samples 41

set xrange[-20:20]
plot int(log10(10**x)) w lp pt 7,\
    x w lp pt 7
### end of code

结果:

在此处输入图像描述

您会看到,在不规则距离中,预期结果和获得的结果之间存在差异。

所以,我仍然缺少一个功能,它总是给我正确的数量级。也许首先将所有数字四舍五入到小数点后 15 位?还有其他想法吗?

标签: gnuplotlogarithmrounding-error

解决方案


假设您处理的数字不超过 12-15 位(或者正如@Ethan 所说,在 64 位系统中超过 15-16 位无论如何都是无稽之谈),以下函数应该给出正确的整数数量级。我只是测试了几个例子,并将其与其他“直接”方法进行了比较。请证明函数对错。

### get the correct power of a number with gnuplot

CorrectPower(n) = floor(log10(n*(1+1e-15)))
IncorrectPower1(n) = floor(log10(n))
IncorrectPower2(n) = floor(gprintf("%T",n))

Numbers = "1e-6 1e-4 0.001 0.01 1e-2 1000 1000000 -1e-6 -1e-9 0.99 95 990"

print " Number    cP  icP1 icP2"
do for [i=1:words(Numbers)] {
    n = word(Numbers,i)
    print \
        sprintf("%7s:%5d%5d%5d", n, CorrectPower(n), IncorrectPower1(n), IncorrectPower2(n))
}
### end of code

结果:

 Number    cP  icP1 icP2
   1e-6:   -6   -5   -6
   1e-4:   -4   -3   -4
  0.001:   -3   -2   -3
   0.01:   -2   -1   -2
   1e-2:   -2   -1   -2
   1000:    3    2    3
1000000:    6    5    6
  -1e-6:   -6   -5   -6
  -1e-9:   -9   -8   -9
   0.99:   -1    0    0
     95:    1    1    2
    990:    2    2    3

加法:对于它的价值,另一个将正确的幂作为整数的函数:

CorrectPower2(n) = int(sprintf("%.15e",n)[19:])


推荐阅读