gnuplot函数中数据类型的条件

时间:2012-07-27 11:32:35

标签: gnuplot

我想定义一个函数,它返回字符串“NaN”或sprintf(“%g”,val),具体取决于val是字符串还是数值。最初我试图测试是否定义了val(使用gnuplot“exists”函数),但似乎我无法将任何未定义的变量传递给函数(在评估函数之前发出错误)。因此:有没有办法在函数内部测试参数是字符串还是数字?

我搜索一个函数isstring,我可以用它来像

myfunc(val)=(isstring(val)?"NaN":sprintf("%g",val))

目标是输出变量的值,而不会在未定义的情况下冒错误。但是,如果我想要一个用于许多变量的紧凑代码,我需要它作为一个函数。

2 个答案:

答案 0 :(得分:2)

Gnuplot并没有真正具备许多其他语言所具有的内省能力。实际上,它非常类似地处理字符串和数字(​​至少是整数):

print "1"+2  #prints 3
a=1
print "foo".a  #prints foo1

我不确定这是如何在内部实施的。但是,你要求的工作非常棘手。

实际上,我认为你的第一次尝试(检查变量是否存在)更合理,因为gnuplot中的类型检查是不可能的*。您可以将变量名称作为字符串传递给函数,但问题是您似乎没有处理该值。所有似乎都丢失了 - 但是等等,gnuplot有一个eval语句,当给出一个字符串时会对它进行评估。这看起来很棒!不幸的是,它是一个声明,而不是一个函数(所以它不能在函数中使用 - argv!)。我能想出的最佳解决方案是编写一个函数,该函数返回一个可以使用eval进行求值的表达式。这是:

def exists_func(result,var)=sprintf("%s=exists('%s')?sprintf('%g',var):'NaN'",result,var,var)

现在,当您想要使用它时,只需在其前面添加eval

a=3
eval exists_func("my_true_result","a")
print my_true_result #3
eval exists_func("my_false_result","b")
print my_false_result #NaN

这与谷物有点不同。在大多数编程语言中,您可能希望执行以下操作:

my_true_result=exists_func(a)

但是,唉,我无法弄清楚如何使这种形式发挥作用。

当然,同样的事情总是伴随着eval。不要将此函数与不受信任的字符串一起使用。

*我实际上并不知道这是不可能的,但我从来没有能够让它工作

修改

在回答您对上述问题的评论时,我认为这样的功能会更直观一些:

def fmt(x)=(x==x)?sprintf("%g",x):"NaN"

使用此功能,您的" sentinal / default"价值应该是NaN而不是"undefined",但它似乎不会产生太大的差异......(真的,如果你愿意和{一起生活} {1}}而不是"nan"你根本不需要这个功能 - "NaN"会很好。(请注意,这是有效的,因为根据IEEE,sprintf不会#39; t等于任何东西(甚至是它自己))。

答案 1 :(得分:1)

这些天你用gnuplot帮助了我很多。我想给你回复一些东西,因为我找到了一个解决方案来检查变量是否为数字。这有助于确定可以在其上使用哪些运算符(例如==表示数字,eq表示字符串)。

解决方案不是很简单,但它有效。它将gnuplot的print命令重定向到临时文件,使用print myvar将变量写入文件,并使用system("perl -e '<isnumeric(line#1 in temp file)?>' ")评估文件的第一行(&lt;&gt;是伪代码)。让我知道是否存在影响力的空间,让我听听你的建议!

示例:myvar是一个浮点数。任何整数(1或“1”)或字符串值(“*”)也有效!

myvar = -2.555  
 # create temporary file for checking if variables are numeric  
Int_tmpfle = "tmp_isnumeric_check"  
 # redirect print output into temp file (existing file is overwritten)  
set print Int_tmpfle    
 # save variable's value to file  
print myvar             
 # check if file is numeric with Perl's 'looks_like_number' function   
isnumeric = system("perl -e 'use Scalar::Util qw(looks_like_number); \  
open(FLE,".Int_tmpfle."); $line = < FLE >; \  
if (looks_like_number($line) > 0) {print qq(y)} ' ")  
 # reset print output to < STDOUT> (terminal)  
set print "-"           
 # make sure to use "," when printing string and numeric values  
if (isnumeric eq "y") {print myvar," is numeric."} else {print myvar," is not numeric."}