算術式の計算
- 再帰処理
このプログラムは再帰処理を利用しています。再帰処理を理解していない場合、まず、再帰処理の項を理解してください。
- 算術式の定義
- 式、項と因子
ここでは (34-56)*(12+5) のような算術式を読み込み、その値を計算します。この処理は言語コンパイラの基本的な処理になります。
算術式では、45+21- 5+... と複数の数値が連続して演算されます。また、26+35*9 では、乗算が加算より優先されますから、35*9
を先に計算する必要があります。さらに、(..) のついた式は乗除よりも優先されます。この優先順序の問題を解決するため、式を項と因子に分解します。因子は数値または
(..) の付いた式で、まず、この因子の値を求めます。次に因子の値を乗除して項を求め、この項を加減算して式の値とします。
- 再帰処理
因子には ( 式 ) の形式が含まれます。つまり、式の計算のためには、項、項の計算に因子、因子の計算には式、の計算が必要となり、ここで再帰処理が起こります。
- 式
式(exp)の構文を図式の形式で以下に示します。最初の "-" は"-"
で減算の記号ではなく、符号を示す演算子です。次に項を計算し、次が "+"または"-"があれば、再び項を計算します。"+"または"-"でなければ、式(exp)の計算は終了です。
項の値を加減算した値が式の値になります。26+35*9 の計算では 26 と 35*9 が項になります。
-24+34*5 の例で最初に現れる"-"が符号演算です。 24と34*5が項になります。式(exp)ではこの項の間の加減算を実行し、その値を式の値とします。
- 項
項(term)の処理はまず、因子の値を計算し、次が"*"または"/"なら続く因子を計算しながら乗除算を計算します。因子を乗除した値が項の値になります。
例えば、26+35*9の場合、26及び、35、9が因子となります。項では、また、26と35*9が項になります。26および35*9の値が項の値となります。
- プログラム:TERM
FACTを呼び出して、因子を計算し、それの乗除算を実行します。
float TERM() /**/
{
char MULOP;
float TV ;
printf(" Term in %c \n",CH);
TV=FACT();
printf(" Term in %f \n",TV);
while ((CH =='*') ||( CH=='/')){
MULOP=CH;
GETCH();
if (MULOP=='*') /**/
TV=TV*FACT();
else
TV=TV / FACT();
}
printf(" Term = %8.2f\n",TV);
return(TV);
}
- 因子
因子(fact)は先頭が "(" なら式の値を再帰呼び出しで計算し、終りの")"を確認します。この場合、式の値を因子の値とします。"("
でなければ数値なので 数値の値を計算し、その値を因子の値とします。
因子の中で式を呼び出していることに注意して下さい。式が項を、項が因子を、因子が式を、呼び出すことにより、式全体の処理が再帰処理になります。
加減算の処理の前に"項"を処理することにより、乗除算を先に実行できます。また、すべての演算の前に "(...)" を処理することで、括弧の優先を定義いることに注意して下さい。
- 例
26+35*9の構造は次の図のようになります。26は乗除算のない項、35*9は二つの因子を乗算した項と解釈されます。また、式全体は二つの項の加算となります。
- 他の例
( 34 - 56 )*( 12 + 5 )+8 の場合、先頭が "(" なので、まず、34
- 56 の式の値を計算します。この値が因子の値になり、項の計算に戻ります。次の文字は"*"なので
因子の計算に戻り、12 + 5 の式の値を計算します。この両者を乗算して項の値が求められます。 次の文字は"+"ですから、項を呼び出し8の値を求めます。項はまず、因子を呼び出し8の値を求め、項に戻ります。"*/"はありませんから、これで項の計算は終了し、式に戻ります。式は、先に求めた(
34 - 56 )*( 12 + 5 )の値と8を加え、次の文字を調べます。"+-"ではありませんから、これで式の処理は終了します。
- 追加機能
上の図式には含まれませんが、因子に以下の機能を追加します。
因子の定数を小数点がついた少数に拡張する。
変数xを指定可能とし、xの値を別途設定可能とする。
したがって、以下のような式の計算が可能となります。
3.4*x*x + 5.2*x +1.3
- プロジェクト
- 概要
式を入力すると、その値を求めて表示します。変数xの値が変化した場合も、再計算をします。
- レイアウト
式と変数xを設定するエディットボックス、と結果を表示するラベルを用意します。式の文字列、変数の文字が変化したとき、対応するイベント処理を実行します。
- 変数
expField1:式を入力するtextFieldです。
xField2:変数xを入力するtextFieldです。
char CH; 式の次の文字を保存します
int CC; 式の次の文字の番号を記録します。
- 関数
- イベント処理
式または変数の値が変化したとき呼び出します。
expField1_actionPerformed(ActionEvent e):式のイベントハンドラ
xField2_actionPerformed(ActionEvent e):変数のイベントハンドラ
どちらも、OnCalc()を実行します。
- GETCH
式の次の文字を読み出します。charAt(CC++)は指定した番号の文字を取り出すメソッドです。
次の文字を読み出し、共通変数CHにセットします。CCは次に読む文字の番号を記録します。また、文字が尽きた場合、'$'を返します。
void GETCH()
{
do{
if (CC >= m_expr.length() ) CH='$';
else CH=m_expr.charAt(CC++);
}while (CH == ' ');
}
- OnCalc
式の文字列と変数xの値を読み込み(UpdateData)、式の最初の文字を読み込み(GETCH)、式の計算をし(EXPV)、その値を表示します。
- EXPV関数
最初に"-"記号の有無を調べます。"-"であれば、次にTERMを呼び出した後、その値(EV)の符号を反転します。次の文字が"+"か"-"であれば、再びTERMを呼び出し、その項の値を求めます。求めた項を先のEVの値に加算または減算した値がこの関数の値となります。続く文字が、"+"か"ー"でなくなれば、EXPVの処理は終了します。
- TERM関数
まず、因子を呼び出し、その値をTVとします。次の文字が"*"か"/"であれば、再び項を呼び出し、その項の値を求めます。求めた項を先のTVに乗算または除算した値がTERMの値となります。続く文字が、"*"か"/"でなくなれば、TERMの処理は終了します。
- FACT関数
- 先頭が(の場合
FACT() では、先頭の文字が "(" なら関数 EXPV() を再帰的に呼び出し、最後に
")" を確認して終了し EXPV() の値を返します。
- 変数xの場合
文字がxなら変数なので、m_xval の値が、この関数の値になります。
- 定数の場合
先頭が数字が数字であれば、小数点の前の数字なら
NUM=NUM*10+(CH-'0');
の計算をして、10進数を数値に変換します。小数点以後の場合、以下のような計算になります。
NUM=NUM+(CH-'0')/10.0f;
この場合、NUMの値がFACT()の戻り値になります。
- 実行例
式および、変数の値を入力します。式には、括弧付きの加減乗除が可能です。
(現在アプレットでは変数が利用できません)
- ダウンロード
このプロジェクトをダウンロードできます。次の行をクリックして、expv.exeファイルを適当なフォルダに保存します。
ダウンロード開始
このファイルは自己解凍型の圧縮ファイルです。このファイルを実行すると指定したフォルダに必要なファイルが生成されます。
トップに戻る