我想定义一个函数,它返回字符串“NaN”或sprintf(“%g”,val),具体取决于val是字符串还是数值。最初我试图测试是否定义了val(使用gnuplot“exists”函数),但似乎我无法将任何未定义的变量传递给函数(在评估函数之前发出错误)。因此:有没有办法在函数内部测试参数是字符串还是数字?
我搜索一个函数isstring,我可以用它来像
myfunc(val)=(isstring(val)?"NaN":sprintf("%g",val))
目标是输出变量的值,而不会在未定义的情况下冒错误。但是,如果我想要一个用于许多变量的紧凑代码,我需要它作为一个函数。
答案 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."}