mod_fx
【作者】 | motchy |
【最終更新】 | 2015/9/5 |
【バージョン】 | 5.1.0 |
【動作確認環境】 | Hot Soup Processor 3.4 以降 (※最新版を推奨) |
【開発環境】 | Hot Soup Processor 3.4 |
目次
文字列で表現された数式の値を求めるモジュールです。
四則演算は勿論、一般的な数学関数、さらに論理演算もサポートします。
HSP標準命令のみで構成されており、DLLを必要としません。
※hsp3dish ではモジュール変数機能とポインタ機能が充実していないので本モジュールは使えません。(2015/08 現在)
mfx_init | モジュールの初期化 | |
HSPランタイム起動後、本モジュールを初めて使用する前に1度だけ呼び出すこと。 | ||
mfx_newVar | 変数作成 | |
mfx_newVar name, isArray, dimension, len | ||
name | 名前 | |
isArray | 配列かどうか(0,1)=(でない,である) | |
dimension | 次元数。例えば2次元配列を定義したいなら2とする。 | |
len | 長さ。int[4]。 要素0~3には各次元方向の長さを格納。 例えば [3,4] 確保したいなら len = 3,4,0.0 とする。 |
|
実行後のstatの値 (-4,-3,-2,-1,other) = (引数不正,変数名不正,既存変数名と衝突,登録数限界超過,登録先ID) |
||
mfx_selVar_name | 操作対象変数を名前で指定する | |
mfx_selVar_name name | ||
name | 名前 | |
実行後のstatの値 (-1,other) : (指定された変数が存在しない,選択された変数のID) |
||
mfx_selVar_id | 操作対象変数をIDで指定する。mfx_selVar_name よりも高速。 | |
mfx_selVar_id id | ||
id | ID | |
実行後のstatの値 (0,1) : (正常終了,指定された変数が存在しない) |
||
mfx_getSelVarName | 選択されている変数の名前を取得 | |
buf = mfx_getSelVarName() | ||
戻り値 (空文字列,other) = (変数未選択,変数名) |
||
mfx_getSelVarID | 選択されている変数のIDを取得 | |
num = mfx_getSelVarID() | ||
戻り値 (-1,other) = (変数未選択,変数のID) |
||
mfx_delVar | 変数削除 | |
操作対象として選択されている変数を削除する | ||
mfx_delVar | ||
実行後のstatの値 (0,1) = (正常終了,変数未選択) |
||
mfx_subst | 変数への代入 | |
操作対象として選択されている変数に値を代入する | ||
mfx_subst val,idx | ||
val | 値 | |
idx | 代入先インデックス。int[4]。 例えば要素(1,2)に代入したければ、idx = 1,2,0,0 とする。 |
|
実行後のstatの値 (0,1,2,3) = (正常終了,変数未選択,配列要素が無効,引数不正) |
||
mfx_newFml | 数式登録 | |
mfx_newFml strFml,errCode | ||
strFml | 文字列数式 | |
errCode | エラーコードを受け取るint型変数。 errCode = 0,0 で初期化しておくべき。 |
|
実行後のstatの値 (-1,other) : (エラー,登録先ID) |
||
mfx_selFml | 数式の選択 | |
mfx_selFml id | ||
id | 数式のID | |
実行後のstatの値 (0,1) : (正常終了,指定された数式が存在しない) |
||
mfx_get_id_selFml | 選択されている数式のIDの取得 | |
num = mfx_get_id_selFml() | ||
戻り値 (-1,other) = (数式未選択,数式のID) |
||
mfx_delFml | 数式の削除 | |
選択されている数式を削除する | ||
mfx_delFml | ||
実行後のstatの値 (0,1) = (正常終了,数式未選択) |
||
mfx_calc | 計算 | |
選択されている数式を計算する | ||
val = mfx_calc(errCode) | ||
errCode | エラーコードを受け取るint型変数。 errCode = 0,0,0 で初期化しておくべき。 |
|
エラーが発生した場合の戻り値はdouble(0) |
1. 始めに必ずやること |
モジュールをインクルードします。スクリプトの冒頭で次のように記述します。
#include "mod_fx.as"
mod_fx.as は /mainUnit/mod_fx.as にありますが、モジュールを使用するときはあなたのスクリプトと同じフォルダにコピーすると良いでしょう。或いは、「HSPのインストールフォルダ/common/」の中にコピーすればあなたのスクリプトと同じフォルダに無くてもインクルードできるようになります。
最初に mod_fxモジュール(※以降単に「モジュール」と称す) を次のようにして初期化します。
mfx_init //モジュール初期化
これで初期化完了です。
2. 最も簡単な練習 |
最も簡単な練習として次の文字列数式を計算してみます。
strFormula = "(1+2)*(3+4)" //文字列数式
コンパイルのエラーコードを受け取るための変数が必要になりますが、ここでは errCode_cmp としておきましょう。これを初期化します。
errCode_cmp = 0,0 //エラーコード用変数を初期化
これで良いです。次に数式をコンパイルしてモジュールに登録します。
mfx_newFml strFormula,errCode_cmp //コンパイル, 登録
これでコンパイル・登録されます。登録先IDはモジュール側が自動で決めます。コンパイル・登録に成功したらIDが stat に格納されます。失敗した場合は stat に -1 が格納され、詳細がエラーコードとして出力されます。
数式は複数登録できますが、計算するときには対象を指定する必要があります。その為に計算対象となる数式を次のようにして選択します。
mfx_selFml 数式のID
今回の練習では
mfx_selFml stat //数式を選択
とすれば良いです。
これで数式が計算できる状態になりました。計算のエラーコードを受け取るための変数が必要になりますが、ここでは errCode_calc としておきましょう。これを初期化します。
errCode_calc = 0,0,0,0 //エラーコード用変数を初期化
これで良いです。
計算結果を mes で画面に出力してみます。
mes mfx_calc(errCode_calc) //計算
画面に 21 と表示されたら成功です。スクリプトはこちらからどうぞ。
同じ要領で次の文字列数式も計算してみてください。
strFormula = "1+1+1/2+1/(3*2)+1/(4*3*2)+1/(5*4*3*2)"
//2.71667
strFormula = "atan(1,-1)/3*4" //3.14159
strFormula = "sin(deg2rad(45))*sqrt(2)" //1
strFormula = "1/factorical(0) + 1/factorical(1) + 1/factorical(2) +
1/factorical(3) + 1/factorical(4) + 1/factorical(5)"
//2.71667
strFormula = "(((1<2)&(2>3))^1)<<2" //4
このように数学関数が使われていたり、( ) が多く複雑だったり、論理演算, ビット演算が使われていても処理できます。
3. 変数を使う |
本モジュールを使用して数学グラフを描いたり、自作ゲームやツールの独自スクリプト/バッチでループ処理を行う場合には変数が使えると便利なことがよくあります。
本モジュールは変数を扱うことができます。変数は非配列でもいいですし、最大で4次元まで配列変数も使えます。
変数は8999個まで定義できますので、事実上無制限と考えて差し支えないでしょう。
3.1. 非配列変数 |
非配列変数 gex を作成して999を代入してみましょう。次のようにします。
len = 0,0,0,0
mfx_newVar "gex",0,0,len
//変数作成
len は配列の長さを指定する int[4]
配列変数ですが、今回は非配列変数を作るので中身はどんな値でも構いません。そこで 0,0,0,0 としました。
第1パラメータは変数名なので "gex" です。
第2パラメータは、配列変数であるかどうかを指定するもので、今回は非配列変数なので0とします。配列変数を作るときは1とします。
第3パラメータは次元数を指定するものですが、今回は非配列変数を作るので中身はどんな値でも構いません。そこで0としました。
これで変数 gex が作成されました。割り当てられたIDがstatに記録されています。作成された直後は変数の内容は0で初期化されています。
このように変数名は1文字とは限らず、文字列でも構いません。大文字,小文字は区別されます。全角文字も使えます。詳しい規則は仕様を参照してください。
変数の作成に失敗した場合はstatに負の整数値が記録されます。詳しい内容はこちらを参照してください。
次に gex に999を代入してみます。
その前に操作対象の変数を選択する必要があります。次のようにします。
mfx_selVar_name "gex" //変数選択
或いは次のようにもできます。
mfx_selVar_id 変数のID
今回の練習では
mfx_selVar_id stat
となります。こちらのほうがより高速です(∵データベースで変数名を検索する手間が省けるため)。
これで gex が操作対象になりました。gex が削除されるか、別の変数を操作対象にするまでは変わりません。
gex に 999 を代入するには次のようにします。
idx = 0,0,0,0
mfx_subst 999,idx
//代入
idx は配列要素を指定する int[4] 配列変数ですが、今回は非配列変数なので中身はどんな値でも構いません。そこで 0,0,0,0 としました。
以上で gex に 999 が代入されました。この状態で次の文字列数式を計算してみましょう。
strFormula = "log10(gex+1)" //文字列数式
「2. 最も簡単な練習」と同じ要領で、次のようにして計算できます。
errCode_cmp = 0,0
//エラーコード用変数を初期化
mfx_newFml strFormula,errCode_cmp //コンパイル,
登録
mfx_selFml stat
//数式を選択
errCode_calc = 0,0,0,0 //エラーコード用変数を初期化
mes mfx_calc(errCode_calc) //計算
画面に 3 と表示されたら成功です。スクリプトはこちらからどうぞ。
3.2. 配列変数 |
大量の情報をまとめて扱うには配列変数が便利です。本モジュールでも配列変数を扱うことができます。
練習として2次元配列 star[2,2] を作成して (0,0) = 1981, (0,1) = 1982, (1,0) = 1983, (1,1) = 1984 としてみましょう。(※「3.1 非配列変数」を先にお読みください。)
次のようにして変数を作成します。
len = 2,2,0,0
mfx_newVar "star",1,2,len
//変数作成
len は配列の長さを指定する int[4] 配列変数です。今回は[2,2]確保するので 2,2,0,0
とします。
第1パラメータは変数名なので "star" です。
第2パラメータは、配列変数であるかどうかを指定するもので、今回は配列変数なので1とします。
第3パラメータは次元数を指定するものです。今回は2次元配列変数を作るので2とします。
変数の作成に失敗した場合はstatに負の整数値が記録されます。詳しい内容はこちらを参照してください。
star を操作対象にします。次のようにします。
mfx_selVar_name "star" //変数選択
値を代入します。今回は次のようにするのがよいでしょう。
i = 1981
repeat 2
cnt0 =cnt
repeat 2
idx = cnt0,cnt,0,0
mfx_subst i,idx
//代入
i ++
loop
loop
以上で代入できました。この状態で次の文字列数式を計算してみましょう。
strFomula = "star(1,1)-star(0,0)+1" //文字列数式
「2. 最も簡単な練習」と同じ要領で、次のようにして計算できます。
errCode_cmp = 0,0
//エラーコード用変数を初期化
mfx_newFml strFormula,errCode_cmp //コンパイル,
登録
mfx_selFml stat
//数式を選択
errCode_calc = 0,0,0,0 //エラーコード用変数を初期化
mes mfx_calc(errCode_calc) //計算
画面に 4 と表示されたら成功です。スクリプトはこちらからどうぞ。
< 数式の文法 >
< トークン長 >
1トークンの長さの最大は127バイト
< 大文字と小文字について >
大文字と小文字は区別される。
< 数学定数 >
次の数学定数はあらかじめ定義されている。
m_pi | 円周率。3.141592653589793。 |
m_e | ネイピア数。2.718281828459045。 |
< 変数 >
変数名には次の規則がある。
■ 長さが127バイト以下
■ 先頭が半角数字でない
■ 括弧,2項演算子と同じ名前が含まれない
■ 予約語と一致しない
変数は8999個まで定義できる。多次元配列も可能で、最大で4次元まで。配列の次元,要素数の拡張は不可能。添え字の記法はHSPと同じ。例えば x(2,3) 。但し () の代わりに [],{} を用いても良い。
新たに定義される変数には0以上のIDが割り振られる。空きIDのうち最も若いものが割り当てられる。また、定義時には変数の内容は0で初期化される。
変数の内容を書き換えただけなら既に登録されている数式を再コンパイルする必要はない。(これを利用して数学グラフ等を高速に描ける)
ある変数xの定義を解除した後に、別の変数yを定義してから変数xを再定義した場合はxのIDは変化するので、変数xを含む、以前の数式は再コンパイルする必要がある。つまり再登録手続きが必要である。
< 利用できる演算子と優先順位 >
< 演算優先順位 >
C言語に倣った優先順序である。
1 | () | 演算順序制御 |
2 | 非配列変数名 | 非配列変数の内容参照 |
配列変数名 | 配列の要素参照 | |
関数名 | 関数呼び出し | |
3 | * | 乗算 |
/ | 除算 | |
% | 剰余 | |
\ | 剰余 | |
4 | + | 加算 |
- | 減算 | |
5 | << | 左ビットシフト |
>> | 右ビットシフト | |
6 | < | 小なり |
<= | 小なりイコール | |
> | 大なり | |
>= | 大なりイコール | |
7 | = | 等価 |
== | 等価 | |
! | 不等価 | |
!= | 不等価 | |
8 | & | |
9 | ^ | ビット積 |
10 | | | ビット排他的論理和 |
11 | , | デリミタ |
< 備考 >
■ 同じ優先順位の演算子が並んでいる場合は左にあるものほど順位が高い。
■ <,>,<=,>= について。例えば a < b が真であれば a < b が double(1) に置き換えられる。
偽であれば 0 に置き換えられる。 ==,=,!=,= も同様。
< ( ) について >
() は次の用途で用いられる。
■ 優先順序制御
■ 配列の添え字
■ 関数のパラメータ
() の代わりに {},[] を用いてもよい。モジュール内部では () と同じものとして扱われる。
< 特殊な規則 >
■ 任意の位置に半角スペースを入れてよい。
< 備考 >
* \ / の右隣に + - を置いても構わない。
(例)
3*-2 ← OK
3*(-2) ← OK
コンパイル結果は同じになる。
< 関数 >
< 利用できる関数 >
sin | 正弦 |
cos | 余弦 |
tan | 正接 |
asin | 逆正弦。asin(u)。 |
acos | 逆余弦。acos(u)。 |
atan | 逆正接。atan(y,x)。HSPのatanと同じ。 |
sinh | 双曲線余弦 |
cosh | 双曲線余弦 |
tanh | 双曲線正接 |
asinh | 双曲線逆正弦 |
acosh | 双曲線逆余弦 |
atanh | 双曲線逆正接 |
sqrt | 正の平方根 |
exp | 指数値。eのx乗。 |
pow | 累乗。powf(底,指数)。 |
log | 対数。log(底,真数)。 |
ln | 自然対数 |
log10 | 常用対数 |
limit | 制限。limit(ターゲット,下限,上限)。HSPのlimitfと同じ。 |
abs | 絶対値 |
floor | 床関数 |
round | 四捨五入 |
ceil | 天井関数 |
int | 0の方向に丸める。HSPのint()と同じ。 |
sgn | 符号関数 |
factorical | 階乗 |
deg2rad | 度数法から弧度法へ変換 |
rad2deg | 弧度法から度数法へ変換 |
< 数式処理 >
< 前提 >
■内部的にはすべての数を64bit精度実数値に拡張して扱う。ビット演算等、整数値に対してのみ有効な演算は、オペランドが整数値の場合に限り実行される。もしオペランドが実数値であればエラーとして扱われる。
■数式は逆ポーランド記法に変換されて管理される。
< エラーコード >
エラーコードを格納する変数を E とすると、Eは要素数2の1次元整数型配列変数であり、エラーコードは配列要素(0),(1)によって、2セクションに分けられている。
< 第1セクション >
エラーが発見されたトークンのインデックス
< 第2セクション >
エラーの原因
0 | 式全体が空文字列である。 |
10 | 不明なトークン |
11 | トークンが長すぎる |
15 | そこに存在してはいけないトークンがある |
16 | 式が正しく終わっていない |
17 | 無駄な , がある |
20 | ( が閉じられていない |
21 | ) 過多 |
30 | 関数のパラメータ不足 |
31 | 関数のパラメータ過多 |
40 | 配列の添え字が無い |
41 | 配列でない変数に添え字が付いている |
42 | 配列の添え字不足 |
43 | 配列の添え字過多 |
50 | その他 |
エラーコードを格納する変数を E とすると、Eは要素数2の1次元整数型配列変数であり、エラーコードは配列要素(0),(1),(2)によって、3セクションに分けられている。
< 第1セクション >
0 : 正常終了
1 : 数式未選択
2 : システムエラー
3 : 数学的エラー
< 第2セクション >
エラーの種類。第1セクションが 2,3 の場合に意味を持つ。
1 | 未定義の変数 |
2 | 配列の添え字が非負整数でない |
3 | 配列の確保済み領域外への参照 |
10 | 非整数に対するビット演算 |
11 | 非整数に対する整数用演算 |
15 | 0除算 |
20 | 関数の定義域逸脱 |
< 第3セクション >
第2セクションが 2,3,10,20 の場合に意味を持つ。
(A) 第2セクションが 2,3 の場合
配列名を格納した文字列型変数へのポインタのintキャステド表現。
内容を確認するには次のようにする。
sdim buf,128
dupptr buf,エラーコードの第2セクション,128,2
dupptrの第4パラメータは vartype("str") としてもよい。
これで buf より変数名を読み出せる。
(B) 第2セクションが 10 の場合
演算子の種類
140 : |
160 : ^
180 : &
240 : <<
241 : >>
(C) 第2セクションが 11,20 の場合
関数の種類
10000 : sin
10001 : cos
10002 : tan
10010 : asin
10011 : acos
10012 : atan
10020 : sinh
10021 : cosh
10022 : tanh
10030 : asinh
10031 : acosh
10032 : atanh
10100 : sqrt
10200 : exp
10220 : pow
10300 : log
10320 : ln
10330 : log10
10400 : limit
10600 : abs
10700 : floor
10720 : round
10740 : ceil
10760 : int
10800 : sgn
10900 : factorical
20000 : deg2rad
20001 : rad2deg
さらに詳しい情報は design/design.txt に書かれています。
motchy が書いたソースコードと関連ファイルはMITライセンスに従います。詳しくは LICENSE.txt を参照してください。
This software's source code and related files made by motchy are released under the MIT license, see LICENSE.txt.
grepon8492.gmail.com
不具合等、お気付きの点がありましたらお気軽にご連絡ください。
但し、対処する保証はありません。
手軽で多機能なプログラミング言語 Hot Soup Processor 開発者の皆様に感謝致します。
[ 2015/9/5 ]
ver 5.1.0
・計算におけるオペレータ処理のアルゴリズムを改良