gnuplot:如何获得正确的数量级? [英] gnuplot: how to get correct order of magnitude?

查看:212
本文介绍了gnuplot:如何获得正确的数量级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题/问题可能与此主题有关 a>.

如果您输入:

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位?还有其他想法吗?

解决方案

假设您处理的位数不超过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:])

This question/issue is maybe related somehow to this topic.

If you type:

print log10(1e7) you will get 7.0.

print int(log10(1e7)) you will get 7.

However, if you type

print log10(1e6) you will get 6.0.

print int(log10(1e6)) you will get 5.

These are probably rounding errors related to log10 and cannot(?) be avoided.

Because if you type

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

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

You can extend and summarize this as a plot: Code:

### 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

Result:

You will see that in irregular distances there are differences between the expected and the obtained result.

So, I am still missing a function which gives me always the correct order of magnitude. Maybe rounding all numbers first to 15 decimal places? Any other ideas?

解决方案

assuming that you are not dealing with more than 12-15 digits (or as @Ethan says more than 15-16 digits in a 64 bit system is nonsense anyway), the following function should give the correct order of magnitude as integer. I just tested a few examples and compared it with other "straightforward" methods. Please prove the function right or wrong.

### 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

Result:

 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

Addition: For what it's worth, another function to get correct power as integer:

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

这篇关于gnuplot:如何获得正确的数量级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆