1

val が文字列か数値かによって、文字列 "NaN" または sprintf("%g",val) を返す関数を定義したいと思います。最初に、val が定義されているかどうかをテストしようとしていましたが (gnuplot の "exists" 関数を使用)、未定義の変数を関数に渡すことができないようです (関数が評価される前にエラーが発生します)。したがって、引数が文字列か数値かを関数内でテストする方法はありますか?

のように何とか使える関数 isstring を探します

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

目標は、変数が未定義の場合にエラーのリスクを冒さずに変数の値を出力することです。ただし、多くの変数に対してコンパクトなコードが必要な場合は、関数として必要です。

4

2 に答える 2

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"が、それほど大きな違いはないようです...(実際、あなたが代わりに一緒に暮らすことをいとわないのであれば"nan""NaN"この関数はまったく必要ありsprintfません-問題なく動作します(IEEEによれば、これNaNは(それ自体でさえ)何にも等しくないため、これは機能することに注意してください)。

于 2012-07-27T13:15:23.497 に答える
1

最近は gnuplot で大変お世話になりました。変数が数値かどうかを確認する解決策を見つけたので、何かお返ししたいと思います。これは、どの演算子を使用できるかを決定するのに役立ちます (例: 数値の場合は ==、文字列の場合は eq)。

解決策はそれほど単純ではありませんが、機能します。gnuplot の print コマンドを一時ファイルにリダイレクトし、変数をファイルに書き込み、print myvarファイルの最初の行を評価しますsystem("perl -e '<isnumeric(line#1 in temp file)?>' ")(<> は疑似コードです)。改善の余地があるかどうかお知らせください。また、ご提案を聞かせてください。

例: myvar は float です。任意の整数 (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."}
于 2013-02-20T12:18:57.133 に答える