fx-9860GII グラフィックス - モンテカルロ法

2015/02/16
2015/02/17 修正
2015/02/22 追記
2015/02/28 追記

fx-9860GII のCasio Basic でグラフィックス表示のプログラムを作ってみようと、色々なコマンドを試行錯誤して試しています。先ずは第一段階として簡単なプログラムを作ってみました。

以前モンテカルロ法による円周率:π を計算するプログラムを fx-5800P で作ったので、今回はこれにグラフィックス表示を追加したプログラムを fx-9860GII で作ってみることにします。
 ⇒ 海外コミュニティー(UCF)での近況

fx-5800P でのモンテカルロ法のプログラム
0→I:0→O
Lbl 1
Ran#2+Ran#2<1⇒Isz I
Isz O
Locate 1,1,O
Locate 1,2,4I÷O
Getkey=0⇒Goto 1


※ 上記エントリーのコメント欄での sentaro様のご指摘に基づき変更しています。


さて、このコンテカルロ法は、2 x 2 の正方形に内接する半径 1 の円を描いておき、その正方形内にランダムに点を打ってゆく時、正方形の中の点の数と円内の点の数から、円周率を求めようと言う考え方です。

 ・[正方形の面積] = 2 × 2 = 4
 ・[円の面積] = 1 × 1 × π = π
なので、
 [正方形の面積] : [円の面積] = 4:π
となります。

これから、
 π = 4 × [円の面積] / [正方形の面積]
となって、円周率の計算ができます。

ところで、ランダムに点を打ってゆくと、円内の点の数(I) が円の面積、正方形内の点の数(O) が正方形の面積としても良いので、円周率:π は以下のようにして求められます。
 π = 4I ÷ O

上のプログラムは、この理屈で(実際は円の1/4 しか使っていませんが...)計算しています。



そこで、今回は同じ理屈で、正方形と内接円に実際にランダムに点を打ってゆく様子をグラフィックス表示しながら、πの計算値がどのように変化してゆくのかを表示するプログラムを、fx-9860GII で作ってみました。但し円全体を使うようにグラフィックスを描画します(円周率の計算は同じです)。

先ずは、プログラムを示します。

プログラム名: MONTECAR
CoordOff
GridOff
AxesOff
LabelOff
ViewWindow -2.8,1.3,0,-1.0087,1.0087,0

0→I:0→O
Circle 0,0,1
Text 1,3,"C="
Text 7,1,"π="
Text 51,3,"(-):Stop"
Text 58,5,"AC:Quit"

Lbl 1

1-2Ran# →X
1-2Ran# →Y
Plot X,Y
X2+Y2<1⇒Isz I
Isz O
Text 1,11,O
Text 7,11,4I÷O

If Getkey=41:Then
Text 51,1,"EXE:Start"
While Getkey  [2015/02/17 削除]
WhileEnd     [2015/02/17 削除]
While Getkey≠31

WhileEnd
Text 51,1,"  "
 (スペース3個)
Text 51,3,"(-):Stop "
 (スペース2個)
IfEnd

Goto 1



プログラム構造

[座標設定]

[初期化処理]

Lbl 1

 [ランダム点の座標計算]

 [ランダム点の描画]

 [点の総数とπの計算値の表示]

 [一端停止と停止解除の処理]

Goto 1

[2015/02/28 追記]
fx-9860GII のプログラムファイル montecar.g1m のダウンロード




まだ、fx-9860GII の Casio Basic コマンドが、メニュー階層のどこにあるのか、完全に把握しきれていないので、コマンドを探すのにチョット苦労しています。とりあえず、以下の入り口から探せばどこかにあり、最悪は [SHIFT] [4] (CATALOG) で探せば必ずあります。

[SHIFT] [F2] (Zoom)
[SHIFT] [F3] (V-Window)
[SHIFT] [F4] (Sketch)

[OPTN]

[SHIFT] [VARS] (PRGM)


[SHIFT] [MENU] (SET UP)


これを起動したところの画面は以下のようになります。

Montecaro-1 

画面左上のCは打った点の総数、π はこの段階で計算した円周率です。
なお、画面左下に

(-):Stop
 AC:Quit


と表示していて、起動直後に [(-)] キーを押してプログラムを一端停止させると、ランダムの点はまばらで、以下のようになります。

Montecaro-2 

[EXE] キーを押して、一端停止を解除し、計算を続行させます。点が少し増えたところで、再び [(-)] を押して実行を止めると以下のようになります。

Montecaro-3 

さらに計算を継続させると、

Montecaro-4 

点の数がかなり増えています。

放置しておくと、正方形の範囲が殆ど塗りつぶされます。

Montecaro-5 

C=27875 にもなっても、まだ一回も点が打たれていないところがあります。Ran# 関数が本当にランダムではないのでしょう。たまたま、円周率の値にかなり近くなっていますが、この Ran# 関数を使ったモンテカルロ法の精度は、あまり高くないと言えそうです。
本エントリーは、グラフィックス描画を試してみるのが目的なので、精度は気にしないでおきましょう。


ところで、点が次々に増えてゆくダイナミックな状態は、見ていて面白いものです。


※ この動画終了後に Functions と言う表示が出ますが、YouTube が勝手に次の動画を紹介しているだけで、本動画とは無関係ですので、無視してください。

この動画は、ノーマルで 29MHz のところ、オーバークロック 280MHz で動作させた時のものです。

描画に時間のかかるグラフィックスプログラムを作って動作確認をする時、待ち時間を短くして動作結果が速く分かるのは、便利です。時間のかかるグラフィックス描画を作る時は、オーバークロック動作をさせています。

私は、オーバークロックには以下のアドインを愛用しています。

 sentaro様作成:Ftune2

オーバークロックでの動作のリスクはゼロではありませんが、このアドインは、プリセットで5つの設定があり、簡単にクロック数を切り替えられます。そして、表示や動作パラメータを確認しながらの設定変更も可能です。リスク低減の配慮がなされており、納得しながらリスクを減らせられるので愛用しています。詳しくは、以下のエントリーをご覧の上、ご興味があれば自己責任でお使いください。
 ⇒ fx-9860GII のオーバークロック - Ftune2 -



さて、今回のプログラムを作るにあたって試行錯誤の結果、Casio Basic でのグラフィックス描画について、いくつか気がついたことがありますので、それを紹介します。


画面のグラフィックス座標設定

グラフィックスは、横127ドット、縦63ドットのドットマトリックス液晶画面で描画します。

点を打つ時は、Plot コマンドでX座標とY座標を指定して、
 Plot X,Y
の書式で点を描画します。X, Y で決まる位置のドット1つが表示されます。

Plot の入力:
[SHIFT] [F4] (Sketch) [F6] [F1] (PLOT) [F1] (Plot)


円の描画は、Circle コマンドで、円の中心のX座標、Y座標、そして円の半径を指定して、
 Circle [中心のX座標],[中心のY座標],[半径]
の書式で円を描画します。

Circle の入力:
[SHIFT] [4] (Sketch) [F6] [F3] (Crcl)

今回は、円の中心が原点(X=0、Y=0)、半径 1 の円を描くので、
 Circle 0,0,1
となります。

実は、fx-9860GII の Casio Basic では、グラフを描画する際には、ViewWindow コマンドで、X軸とY軸の範囲を指定することで、画面全体の座標系を決めます。これを利用すれば、例えばX軸の範囲、つまりXの最小値と最大値を -2.0 と 2.0 に設定すると座標の原点は中央に来ます。Xの最小値を -3.0、最大値を 1.0 にすれば、原点は中央から右にずれます。

ViewWindow の入力:
[SHIF] [F3] (V・WIN) [F1] (V・WIN

ViewWindow は、グラフ用紙のようなものです。グラフ用紙に円を描き、用紙を右に移動させれば、当然ながら描いた円も一緒に移動します。

そこで、今回のプッログラムでは座標の設定を以下のようにしました。

ViewWindow -2.8,1.3,0,0-1.0087,1.0087,0

書式は、以下になります。
ViewWinow [X最小値],[X最大値],[X軸の目盛り間隔],[Y最小値],[Y最大値],[Y軸の目盛り間隔]

今回のプログラムでは、
 ・X最小値: -2.8
 ・X最大値: 1.3
 ・X軸の目盛り間隔: 0
 ・Y最小値: -1.0087
 ・Y最大値: 1.0087
 ・Y軸の目盛り間隔: 0

としています。

なお、画面のX方向(左右)は、左端のドットの中心と右端のドットの中心の距離は 126 ドット分 、これに対して左右のXの範囲は 1.3 - (-2.8) = 4.1 に相当します。
液晶上端のドット中心と下端ドット中心の距離は 62 ドット分なので、左右と同じ縮尺で上下のYの範囲を設定するには、

4.1:[Yの範囲] = 126:62

従って、[Yの範囲] = 4.1/126 × 62 = 2.017460317 なので、ここでは半分の値を使って、
 ・Y最小値: -1.0087
 ・Y最大値: 1.0087
と、上下は対称になるように設定しました。

画面の横幅(126ドット分)と縦幅(62ドット分)は厳密に 2:1 にはなっていないので、126対62になるように細かく設定することで、原点の回りに対称な円を描けました。

もしX軸とY軸の縮尺が異なると、この円は真円にならず、楕円になります。ゴムの上に円を書き、ゴムを一方向に引っ張ると円が楕円になるのと同じです。

この円の直径は 2 ですが、座標の設定で上下と右端に少し余裕を持たせていることに、お気づきでしょう。敢えて余裕を持たせています。

なお、引数の3つめと6つめのX軸とY軸の目盛り間隔ですが、これを 0 に設定してもエラーにならないので、今回は 0 としました。仮に 1 としても描画に変化がありません。以下に説明するように 座標軸の表示をしない設定(AxesOff コマンド使用)にしているので、影響が無いと思われます。 


このように、fx-9860GII の Casio Basicでは、グラフィックスを描画する前にグラフの描画範囲(座標)をうまく設定するのがコツのようです。最初に ViewWindowで座標を決めれば、PlotCircle はその座標系で描画できます。ViewWindow で座標設定が簡単にできるので、利便性が高いと思います。

但し、ブラフ表示を目的として各種コマンドが準備されていると考えるべきで、その場合は軸の名前(X や Y)の表示、グリッド表示、座標軸表示、目盛り表示、ラベル表示は今回のプログラムでは不要です。幸いなことに、これらの表示をオフにするコマンドが準備されているので、それを使います。

CoordOff
GridOff
AxiesOff
LabelOff


CoordOff の入力:
[SHIFT] [MENU] (SET UP) [F2] (COOR) [F2] (Off)

GridOff の入力:
[SHIFT] [MENU] (SET UP) [F3] (GRID) [F2] (Off)

AxesOff の入力:
[SHIFT] [MENU] (SET UP) [F4] (AXES) [F2] (Off)

LabelOff の入力:
[SHIFT] [MENU] (SET UP) [F5] (LABL) [F2] (Off)



テキスト表示

fx-5800P で作ったプログラムのように、打った点の数と円周率π の計算値を画面表示させます。
Locate コマンドを使うと、画面がちらつきます。Locate" " (出力)命令などのテキスト表示の時にはグラフィックスが表示されず、グラフィックス表示の時にはテキストが表示されません。結果的にテキスト表示とグラフ表示が頻繁に切り替わるので、表示がちらつきます。テキスト表示とグラフィックス表示では異なるRAMを使っていると思われ、同時表示の方法がまだ見つかっていません(できないかも知れません)。

Text の入力:
[SHIFT] [F4] (Sketch) [F6] [F6] [F2] (Text)

Text の書式:
 Text [文字の左上のドットのY座標],[文字の左上のドットのX座標],[表示内容]
 ※ 表示内容には、数値、変数、式、戻り値のある関数が使えます(Locate と同様)

一方、Locate の書式は、Locate [X座標],[Y座標],[表示内容]

なので、座標指定のXとYが互いに逆になっています。

なお、Text コマンドで表示される文字や数字は、Locateコマンド" "(出力)命令 のような見やすいフォントを使った表示ではなくて、液晶のドットを使った単純な文字表示です。そして、1文字の表示で使う縦横のドット数が異なりますので、表示位置のY座標とX座標は文字に合わせて微調整しました。

数字は、縦5ドット、横3ドットのようですが、小さな数字も使えるので、その場合は文字に合わせる必要があります。一方で、表示の位置は Locate コマンドのように縦横の位置が決まっていないので、好きな位置に表示可能な利点もあります(面倒ですが...)。



ランダムな点の位置計算と描画

ランダムな点を Plot X,Y で表示させています。

fx-5800P で作ったプログラムでは、ランダムな点の座標(X,Y) のXとYは、いずれも 0~1 の範囲の正の数としていました。

今回は、グラフィックスの見栄えを考えて、半径1の円に外接する1辺が 2 の正方形の範囲全体にランダムに点を打つようにしています。従って、X と Y は、それぞれ -1 ~ +1 の範囲の値にしたいわけです。

そこで、一旦 Ran# 関数で、0~1 の値を得るまでは同じですが、これを 2 倍して、1 から引き算することで、-1 ~ +1 を算出するように変更しました。

1-2Ran# →X
1-2Ran# →Y


次に、点(X,Y) が円の中に入っているかどうかは、

X2+Y2<1

で判定し、これが正しい時に 円内の点の数 I を1つ増やす処理を行っています。

X2+Y2<1⇒Isz I

X と Y は、必ず -1 ~ +1 の間の数なので、必ず 2x2 の正方形の中の点です。そこで、無条件に Isz O で1つ増やす処理にしています。また、点は 必ず 2x 2 の正方形内に打たれることが、上記から保証されるので、描画範囲を決める座標設定 (ViewWindowコマンド) で、2 x 2 よりも少し広い範囲に設定しても問題がなく、見栄えが良くなるわけです。

打った点の総数やπの計算値の表示には Text コマンドを使って、以下のようにグラフィックス画面に表示します。

初期表示の部分で、

Text 1,3,"C="
Text 7,1,"π="


とし、Lbl 1/Goto 1 ループの中では、点1を1つ打つたびに、以下の表示を行います。

Text 1,11,O
Text 7,11,4I÷O




プログラム操作に関する部分

[(-)] キーを押した時、プログラムを一旦停止させ、[EXE] キーで一旦停止を解除する部分、それに伴う表示の変更は、以下のようにしました。

[(-)] キー(キーコード41)が押された時の必要な処理を行うので、

If Getkey=41:Then
[必要な処理]
IfEnd


としました。
プログラム全体は、Lbl 1 / Goto 1 で無限ループになっていて、If Geykey=41 はループが回るたびに実行されるので、上記のようにできます。

[必要な処理] については、 [EXE] キー(キーコード31)が押されるまでループを回し続けてプログラムが先に進むのを防ぎ、これが押されたら次へ進む、と言うロジックにしています。

表示の変更も織り込みました。

If Getkey=41:Then
Text 51,1,"EXE:Start"

While Getkey≠31
WhileEnd
Text 51,1,"  "
  (スペース3つ)
Text 51,3,"(-):Stop "
 (スペース2つ)
IfEnd


スペースは、上書きして前の表示を違和感なく消すために使っています。


[2015/02/27 修正]
当初、[EXE]のトグル操作で一旦停止と解除を実装していて、そのために以下の赤文字の2行を入れていました。
If Getkey=31:Then
Text 51,1,"EXE:Start"
While Getkey
WhileEnd

While Getkey≠31
WhileEnd
Text 51,1,"EXE:Stop"
IfEnd


その後、グラフィックス以外のコードを単純化するために今回の仕様に変更しましたが、その際不要なコード2行を削除し忘れていました。



今回のプログラムを作ってみて分かったことは、グラフィックス描画の前に、画面全体の座標設定(座標変換)を ViewWindow コマンドで行うと、この座標系で PlotCircle コマンドによる点や円の描画が楽にできるということです。

テキスト表示も Text  コマンドが使えて、Locate コマンドよりも柔軟性が高いことも分かりました。但しフォントが少しお粗末ですが...

実は、今回のプログラムの ViewWindow コマンドの部分を、以下の2行に置き換えるだけで(他の部分の変更無しで)、ほぼ同じように正常動作します。

ViewWindow -20.85,19.35,0,-10.05, 10.05,0
Factor 10,10


これについては、もう少し調べたいことがあるので、とりあえずメモ代わりにここに置かせてもらいます。



[2015/02/22 追記]

グラフィックス描画速度について

今回の Casio Basicプログラムとほぼ同じロジックを使って、sentaro様が Add-in プログラムを作ってくださいました(コメント欄参照)。そこで、画面描画もほぼ同じになるように改造させて頂きました。実行速度に大きな違いはありませんが、add-in 作成の練習を兼ねて改造させてもらいました。
 ⇒ sentaro様作成の Add-in、montecar.g1a: ダウンロード
 ⇒ 私が手を入れた Add-in、monteca2.g1a: ダウンロード
※ ダウンロードした ZIP ファイルには、add-in プログラムと Casio SDK でビルド可能なソースファイルが含まれています。

Add-in プログラム monteca2.g1a を fx-9860GII に転送すると、[MENU] キーで現れる MAIN MENU 画面に、この Add-in が表示されています(画面の右下)。

Main_Menu_Monteca2 

なお、この add-in には、実行時間を計測するルーチンが組み込まれていて、ストップウォッチ無しでも実行時間の計測ができるようになっています(この部分が sentaro様オリジナルの非常に役立つルーチンで、(ここだけがオリジナルの Casio Basic プログラムと異なります)。

Add-in_Monteca2 

Casio Basic プログラムと、ほぼ同じ画面になっていることが分かります。なお、 t= 7.04s と実行時間が表示されています。

やはりC言語で作るプログラムは Casio Basic よりも圧倒的に速いです。どれぐらい速いか、見てみましょう。



これは、ノーマルクロック (29MHz) でのものです。
動作モードメニューで、

 F1:MonteCarlo 1/1
 F2:MonteCarlo 1/10
 F3:MonteCarlo 1/100
 
 F5:MonteCarlo bench
 F6:MonteCarlo bench 2


と表示され、上から順に [F1] から順に [F6] まで実行しています。

オーバークロック (280MHz) では、さらに速くなります。



[F1] から順に [6] まで5つの動作モードで動作しています。圧倒的速さを実感できます。

さて、fx-9860GII のノーマルクロック 約29MHzと、オーバークロックした約 280MHz も併せて試した結果を以下に示します。
測定は、点の総数が100個程度になったら実行を止めて、その時間と点の総数を5回測定。これから点100個あたりの時間を計算し、最大値と最小値を取り除き、残る3回の平均を計算して、ループ1回あたりの実行時間を得ました。Add-in は、複数の動作モードから、オリジナルの Caso Basic に最も近い [F1] のモードを使用しました。

プログラムCasio BasicAdd-in
動作クロック (MHz)約29約280約29約280
ループ1回の実行時間 (ミリ秒)27843.621.07.40
速度比率 (全体)16.4倍13.2倍37.6倍
速度比率 (Basic と Add-inの比較) - 280MHz---1---5.9倍
速度比較 (29MHz と 280Mhzの比較 - Add-in------12.8倍

・ ノーマルクロックでは、Casio Basic のままオーバークロックするよりも、C言語によるAdd-in の高速化が顕著(2倍)です。

・ オーバークロックの効果は、C言語による Add-in よりも Casio Basicの方がその効果は顕著(約2倍)です。

今回のように、画面を埋め尽くすようなグラフィックス描画を高速に動作させたい場合は、C言語による Add-in を考えるべきです。

しかしCasio SDK によるプログラム作成の敷居の高さを考えると、次善の策として Casio Basic で作ってオーバークロックと言う方法があります。

そして、fx-9860GII USB POWER GRAPHIC2 (現行機種) は、他のグラフ関数電卓の現行機種と比べて、オーバークロックツール Ftune2 で最大限の効果が得られます(コメント欄参照)。モノクロ表示ですが、fx-9860GII の価値は高いと言えます。

Casio Basic 搭載のグラフィックス機能は、グラフ描画機能に特化したもので、グラフ作成のための多彩な機能がある一方で、描画点数の多いグラフィックス表示は、かなり遅いことが定量的にわかりました。


なお、この測定のために、円の描画と必要な表示の後に一端停止し、[EXE] キーで停止を解除するように Casio Basic プログラムを変更しました(下記参照、追加した部分を赤文字で示す)。Add-in プログラムの時間測定が、初期描画終了後、ループに入る手前で測定開始するようになっているので、それに合わせました。

※ fx-9860GII に転送して使える Montecar.g1m のダウンロード

fx-9860GII プログラム: Montecar
CoordOff
GridOff
AxesOff
LabelOff
ViewWindow -2.8,1.3,0,-1.0087,1.0087,0

0→I:0→O
Circle 0,0,1
Text 1,3,"C="
Text 7,1,"π="
Text 51,3,"EXE:Start"
Text 58,5,"AC:Quit"

While Getkey≠31
WhileEnd
Text 51.1." "
Text 51,3,"(-):Stop "


Lbl 1

1-2Ran# →X
1-2Ran# →Y
Plot X,Y
X2+Y2<1⇒Isz I
Isz O
Text 1,11,O
Text 7,11,4I÷O

If Getkey=41:Then
Text 51,1,"EXE:Start"
While Getkey≠31
WhileEnd
Text 51,1,"  "
 (スペース3個)
Text 51,3,"(-):Stop "
 (スペース2個)
IfEnd

Goto 1







応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



 


keywords: fx-9860GIICasioBasicプログラム関数電卓

リンク集 | ブログ内マップ


関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

Casio Basic入門41

Casio Basic(超)入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

2015/02/21
2015/03/01 修正


 4. CasioBasicを使ってみる(続き)


Chapter 7  - 初級

前回: Casio Basic入門40


◆ Chapter 7 の目標: ゼロからのプログラム作成と機能追加

前回は、摂氏温度、華氏温度、絶対温度の間で換算するプログラムを作りました。

プログラム TC3

"1:°C"
"2:°F"
"3: K"
"INPUT MENU N°"?→M

Cls
If M=1:Then
"°C"?C
(9÷5)C+32→F
C+273.15→K
Else If M=2
Then
"°F"?F
5(F-32)÷9→C
C+273.15→K
Else If M=3
Then
"K"?K
K-273.15→C
(9÷5)C+32→F
IfEnd:IfEnd
IfEnd

Cls
"1:"
"2:"
"3:"
Locate 4,1,C
Locate 4,2,F
Locate 4,3,K
Locate 13,1,"°C"
Locate 13,2,"°F"
Locate 13,3," K"


このプログラムの構成は、

メニュー選択させた後、それぞれ
 1) 入力: 数値を入力させ
 2) 計算: 計算して
 3) 出力: 結果を表示する

と、なっています。

このプログラム TC3 を使っていて、たまに妙なバグが発生することがあります。

TC3 を起動すると、以下のメニュー画面が表示されます。

TC3-2 

メニュー番号1~3 を入力すべきところ、138 と入力して、

TC3-4 

ここで、[EXE] で入力確定すると、 

TC3-3 

摂氏 0 ℃、華氏 -1℃、絶対温度 10K となってしまい、これは絶対に間違った表示なので、バグと言えます。そもそもメニュー番号を間違って入力したのがいけないので、バグがあっても自分で正しく使えば良いのです。

今回のケースでは明かにバグと分かる表示ですが、これが正しい値ではないけれど、それに近い間違った表示だった場合、換算プログラムとしてはマズイし、プログラムが想定外の動作をするのは気持ちが悪いので、原因を調べて、簡単に修正できれば修正しようと思います。



Chapter 7-4
バグの原因と対処 - フラグの利用

問題の原因を探すために、プログラムは上から下へ順に実行されると言う基本に従って、作ったプログラムを上から順に追いかけて、詳細にシミュレーションしてみます。

"1:°C"
"2:°F"
"3: K"
"INPUT MENU N°"?→M


ここまでは問題ない筈です。メニューが表示されてキー入力待ちになっています。

ここで、138 と入力して [EXE] を押すと、M138 が代入されます。

すると、先ず Cls で画面表示が消去され、内部カーソル行がリセットされて 1 行目になります。これに続部分で If から IfEnd までは、M138 だと言う条件に合わないので、何も実行されません。

Cls
If M=1:Then
"°C"?C
(9÷5)C+32→F
C+273.15→K
Else If M=2
Then
"°F"?F
5(F-32)÷9→C
C+273.15→K
Else If M=3
Then
"K"?K
K-273.15→C
(9÷5)C+32→F
IfEnd:IfEnd
IfEnd


ここまでは、問題無さそうです。この後に以下のコードが続きます。

Cls
"1:"
"2:"
"3:"
Locate 4,1,C
Locate 4,2,F
Locate 4,3,K

Locate 13,1,"°C"
Locate 13,2,"°F"
Locate 13,3," K"


最初の4行は、特に問題なく表示されます。その下の Locate を使った3行(赤文字で示している部分)を調べます。

TC3-3 

問題が発生する時には、このように表示されるのですから、変数 C に 0変数 F に -1変数 K に 10 が格納されていることになります。この3行の Locate を使ったプログラムは正常に動作していて、変数が異常になっていることが疑われます。

そこで、この推測を検証するために、敢えて以下のコードをプログラムの先頭、つまり "1:°C" の上に追加してみてください。

0→C:-1→F:10→K

これを実行します。最初に表示されるメニュー画面で 138 と入力して [EXE] を押すと、上と同じ表示になりました。バグに再現に成功しました。これで、変数に格納されている数値に異常があったことが確認されました。

次に、なぜ変数の異常が発生したのかを調べます。

fx-5800P はプログラムTC3 を走らせるだけでなく、普通に電卓として使ったり、他のプログラムを実行して使います。すると、変数 C、F、K に何かの値が格納される可能性があります。するとTC3を起動した時、変数 C0F-1K10 が格納されている可能性が確かにあります。これらの変数に別の数値が格納されている可能性だって十分にあります。

そして、メニュー番号の入力で 1~3 以外にすると、メニュー番号に応じた処理がまるまる飛ばされるので、本来 C、F、K に新たに値が代入される機会がないまま、これらの変数に格納されている値が Locate コマンドで表示されてしまいます。これがバグの原因です。

Casio Basic のコマンドに、ClrMemory コマンドがあります。プログラムの冒頭でこれを実行するとどうなるでしょうか?

ClrMemory を入力するには、
[FUNCTION] [6] (6:CLR) と入力して CLRメニューから [2] (2:Memory) を入力します。

ClrMemory は、全ての変数に 0 を代入するコマンドです。言い換えれば全ての変数を 0 で初期化します。

TC3-5 

すると、変数 C、F、K0 が格納されます。そして、今回のバグの条件、つまりメニュー番号入力で 1 ~ 3 以外の数を入力すると、以下のような表示になります。

TC3-6 

これも間違った表示ですね。つまり、ClrMemory ではバグ対策にはなりません。


そこで、メニュー番号入力で、1 ~ 3 の入力があったときだけ、つまり変数 C、F、K に正しい値が代入された時だけ、これら変数をを表示させるようにします。

具体的には、正しいメニュー番号を入力して、メニュー番号に応じた処理が実行された時だけ、

Locate 4,1,C
Locate 4,2,F
Locate 4,3,K


の3行を実行させ、そうでない時はこの3行を実行させない方法を考えます。

これを実現するためには、幾つかの方法が考えられます。
今回は、新しい変数 A を導入した上で、以下のようにします。追加した部分を赤文字で示します。

0→A
"1:°C"
"2:°F"
"3: K"
"INPUT MENU N°"?→M

Cls
If M=1:Then
"°C"?C
(9÷5)C+32→F
C+273.15→K
1→A
Else If M=2
Then
"°F"?F
5(F-32)÷9→C
C+273.15→K
1→A
Else If M=3
Then
"K"?K
K-273.15→C
(9÷5)C+32→F
1→A
IfEnd:IfEnd
IfEnd

Cls
"1:"
"2:"
"3:"
If A=1:Then
Locate 4,1,C
Locate 4,2,F
Locate 4,3,K
IfEnd
Locate 13,1,"°C"
Locate 13,2,"°F"
Locate 13,3," K"


この変更では、変数 A を追加し、プログラム開始時に A0 を入れておきます。そして、正しくメニュー番号を入力して、メニュー番号に応じた処理を行った時にだけ A1 を入れるようにします。変数 C、F、K の値を表示する Locate コマンドを使った3行は、If A=1 による条件判断で、A が 1 の場合に、この3行を実行します。

このような方法は、Casio Basic に限らずあらゆるプログラミング言語で一般的に使われます。変数 A を「フラグ」と呼びます。フラグ (flag) =旗 です。何かの条件を満たす時旗を揚げ、そうでない時は旗を下げます。そしてこの旗が上がっているか上がっていないかで、処理の分岐を行うと言うテクニックです。

旗を揚げることを「フラグを立てる」と言います。フラグには変数を用いて、フラグが立っていない時は 0 としておき、フラグを立てると 0 以外の値にするのが一般的です。

上のプログラムでは、フラグの変数を A としてい、以下のような If 構文を使っています。

If A=1:Then
<フラグが立っている時の処理>
IfEnd


ところで、この処理は以下のようにしても正しく動作します。

If A:Then
<フラグが立っている時の処理>
IfEnd


Casio Basic コマンドリファレンス - If 文 でも説明しているように、If の条件判定に変数だけを使うこともできます。

変数 A0 の時 If A は「」、つまり条件に合わない、と判定し、A0 以外の時 If D は「」、つまり条件に合う、と判定するのです。If の条件判断に変数を指定できるのです。

この仕様は、一般に多くのプログラミング言語で採用されているもので、Casio  Basic でも、この一般的な仕様を採用しています。Casio Basic が登場する前のカシオのプログラム電卓には無かった仕様で、新世代 Casio Basic は、しっかりした言語だと言えます。

そこで、値の表示を行う上記3行のコードを、以下のように記述できます。

If A:Then
Locate 4,1,C
Locate 4,2,F
Locate 4,3,K
IfEnd


If A という記法は他の言語でも一般的に使えるので、覚えて損はありません。

この記法には、もう一つの利点があります。fx-5800P は処理速度が遅いので、色々とプログラムを作るようになると、処理を速くしたいことが必ずあります。If A は If A=1 に比べて処理速度が2倍以上速いので、役立ちます。
 ⇒ fx-5800P:変数アクセス、比較・論理演算、条件分岐の速度比較


では、プログラム名を TC3 から TC4 に変更した後、上記の変更を行います。

COMPモード[MODE] [5] (5:PROG) と入力して、Program Menu に入ります。

Program Menu 

ここで、[3] (3:Edit) を入力して、Prog Edit 画面に切り替え、TC3 にカーソルを合わせます。

Prog Edit TC3 

ここでファイル名 TC3 から TC4 に変更してみます。

Prog EditTC3 にカーソルが合っている状態で、[FUNCTION] を押すと、File Commands メニューが現れます。

File Commands 

ここで、[2] (2: Rename) を入力し、File Name? 画面に切り替えます。

File Name TC3 


この状態では、画面上部に A アイコンが表示されていることからも分かるように、アルファベットモードになっています。[ALPHA] キーを押して、アルファベットモードを解除してから、末尾の 3 を消去して 4 に変えます。

File Name TC4 

[EXE] で確定し、Prog Edit 画面へ戻ります。

Prog Edit TC4 

[EXE] で確定すれば、プログラム編集画面が開きます。

TC4-1 

あとは、コードを変更します。以下に従ってプログラムを修正しましょう。

プログラム TC4
0→A
"1:°C"
"2:°F"
"3: K"
"INPUT MENU N°"?→M

Cls
If M=1:Then
"°C"?C
(9÷5)C+32→F
C+273.15→K
1→A
Else If M=2
Then
"°F"?F
5(F-32)÷9→C
C+273.15→K
1→A
Else If M=3
Then
"K"?K
K-273.15→C
(9÷5)C+32→F
1→A
IfEnd:IfEnd
IfEnd

Cls
"1:"
"2:"
"3:"
If A:Then
Locate 4,1,C
Locate 4,2,F
Locate 4,3,K
IfEnd
Locate 13,1,"°C"
Locate 13,2,"°F"
Locate 13,3," K"

これで、バグの修正ができました。追加部分を赤文字で示しています。



今回は、フラグと言う考え方を紹介し、想定外の入力に対してでも異常動作しないようにバグを修正しました。
プログラムには正解が1つあるものではありません。正しく動けば正しいプログラムです。色々な流儀や好みもあります。

プログラムをブロック構造にしておき、追加や変更するブロック以外には手を付けずそのまま残しておけるのが、バグの出にくいプログラムと言えます。今回紹介したようなフラグの使い方は、変更時にもバグの出にくいテクニックとして紹介しました。

これで、十分実用的なプログラムが完成しました。表示の一部と計算を変更すれば、様々な換算プログラムを作れるようになったと思います。TC4 を改造したり流用して、色々なプログラム作りに挑戦してみてください。

次回は表示を少し変更してみます。

TC4 起動時の画面は以下のようになります。

TC4-2 

これを、下の写真のような換算結果画面と同じ画面構成に変更しようと思います。

TC4-4 


次回までに、ご自分で改造に挑戦してみてください。



つづく...

Casio Basic入門42 / 目次




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ

 


keywords: fx-5800PCasioBasic、入力ボックス, プログラミング入門プログラム関数電卓、温度換算

リンク集 | ブログ内マップ



関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

楽屋裏 - Casio Basic のグラフィックス描画

楽 屋 裏
e-Gadget

2015/02/17

fx-9860GII の Casio Basic でグラフィックス描画を色々と触っていて、どのようなプログラムを作れるのか興味を持っています。

モンテカルロ法をグラフィックス化してみましたが (fx-9860GII グラフィックス - モンテカルロ法) ノーマル(29MHz)では描画速度が遅いので、オーバークロック(280MHz)で少しマシになる程度です。

全画面描画のプログラムは、現実使い物にならない可能性が高く、ライフゲームなど作ってみたいと思ったのですが、チト無理そうです。

例えば、各ドット(ピクセル)を、表示する/しないの判定をして、全画面表示するとその遅さが分かります。

千鳥配置でドット表示
CoordOff
GridOff
AxesOff
LabelOff
ViewWindow 0,126,0,0,62,0
For 0→Y To 62
For 0→C To 126
Mod(X+Y)⇒Plot X,Y
Next:Next



乱数でドット表示
CoordOff
GridOff
AxesOff
LabelOff
ViewWindow 0,126,0,0,62,0
For 0→Y To 62
For 0→X To 126
Ran# >0.5⇒Plot X,Y
Next:Next



全画面表示を伴うグラフィックスは、オーバークロックしてもCasio Basic には向かなくて、Cで書く必要がありそうですね。

「千鳥配置でドット表示」で、CoordOn に変更したり、ViewWindow 0,127,0,0,63,0 に変更したりすると、何がどう変化するのか分かって面白いです。ViewWindow は何か色々とありそうです。






応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


keywords: fx-5800PCasioBasic換算プログラムプログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ
関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

Casio Basic入門40

Casio Basic(超)入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

2015/02/21 修正


 4. CasioBasicを使ってみる(続き)


Chapter 7  - 初級

前回: Casio Basic入門39


◆ Chapter 7 の目標: ゼロからのプログラム作成と機能追加

前回は、摂氏から華氏、華氏から摂氏を選んで温度換算するプログラムを作りました。

プログラム TC2

"1:°C"
"2:°F"
"INPUT MENU N°"?→M

Cls
If M=1:Then
"°C"?C
(9÷5)C+32
Else If M=2
Then
"°F"?F
5(F-32)÷9
IfEnd:IfEnd


このプログラムの構成は、

メニュー選択させた後、それぞれ
 1) 入力: 数値を入力させ
 2) 計算: 計算して
 3) 出力: 結果を表示する

と、なっています。



Chapter 7-3
選択肢3つの換算プログラムに拡張する

これまでのプログラムでは、最後に計算を行った結果が表示されると言う Casio Basic の性質を利用しています。
ところが、絶対温度を計算して表示させる機能を追加することを考えてみると、3つの温度単位のうちどれか1つで温度値を入力した後、残り2つの単位の温度値を表示しなければなりません。今のままだと、最後に計算した値しか表示されないので、うまくゆきません。そこで、計算した結果を変数に入れておき、計算が終わった後、改めて変数を表示するようにすれば、2つの値を表示できます。

この作戦に沿って、前回のプログラムを変更して、摂氏温度と華氏温度の両方を表示するように変更してみます。追加した部分を赤文字で示します。

"1:°C"
"2:°F"
"INPUT MENU N°"?→M

Cls
If M=1:Then
"°C"?C
(9÷5)C+32→F  ・・・(1)
Else If M=2
Then
"°F"?F
5(F-32)÷9→C  ・・・(2)
IfEnd:IfEnd

Cls           ・・・(3)
"1:°C"
"2:°F"
Locate 6,1,C
Locate 6,2,F



変更部分の説明

(1)
摂氏から華氏温度へ換算した結果を変数 F に代入(格納)しておきます。

(2)
華氏から摂氏温度へ換算した結果を変数 C に代入(格納)しておきます。

(3)
一旦画面を消去し、内部カーソル行をリセットして1行目に戻します(Cls の仕様)。
次に、プログラムの最初と同じ表示を行います。
 1:°C
 2:°F

最後に、Locate コマンドを使って、この2行の右へ、それぞれ摂氏温度と華氏温度を表示します。

Locate コマンドは、画面内の好きな位置へ表示を行えるものです。出力命令" " との最大の違いは、表示位置の柔軟性が高いことにあります。


命令とコマンド
これまで、?(入力)命令" "(出力)命令Cls コマンドが出てきて、そして今回は Locate コマンドが出てきました。
命令とコマンドは、同じ意味ですが敢えて使い分けています。
Casio プログラム電卓で以前から有ったもので、新世代 Casio Basic でも残っているものを「命令」と呼ぶことにしています。
そして、Basic としてのものを「コマンド」と呼ぶことにしています。

旧来の命令
Chapter 7 では、以前からある「命令」を使うことで、シンプルなプログラムを作ることを優先させています。旧来の「命令」は、これまでに見てきたように、多彩な機能を内蔵しています。それを理解すれば、簡単なプログラムがとてもシンプルに作れることを、既に体験してもらっています。

Casio によれば、旧来の命令に慣れ親しんだユーザーの利便性を考えて、新世代 Casio Basic でも旧来の命令を残しているとのことです。私がこれまで調べてきた結果、旧来の命令の利便性を最もよく考えられているのが fx-5800P です。一方で、高機能で高価なグラフ関数電卓(fx-9860GII、fx-CG20/10)や fx-FD10 Pro では、旧来の命令は残っているものの、その詳細な機能は fx-5800P とは異なっていて、使いづらくなっています。私が自作プログラムを使うために fx-5800P を愛用している理由の1つが、旧来の命令の利便性が高い点にあります。詳しくは以下のエントリーをご覧ください。

 ⇒ (参考) fx-9860GII への移植 - 厄介な旧来の命令


話を元に戻します。

Locate の書式は、以下のようになります。

Locate [桁],[行],[表示内容]
 ・3つのパラメータ(引数)をコンマ , で区切って記述
 ・[桁] は、画面左端が 1、右端が 16 で、1~16 のいずれかの数
 ・[行] は、画面上端が 1、下端が 4 で、1~4 のいずれかの数
 ・[表示内容] には、文字列、数値、変数、式、戻り値のあるコマンド(Getkey)のいずれも設定できる
   文字列を設定する場合は、" "  の中に表示したい文字列を記述する。

※ 文字列表示の時の " "  の中以外でスペースを入れるとエラーとなる。
※ 表示結果が、16桁、4行を超える場合はエラーとなる。

 ⇒ Casio Basic コマンドリファレンス - Locate


例えば、
"1:°C"
"2:°F"
Locate 6,1,C
Locate 6,2,F


 を実行すると、Locate コマンドは、6桁目、1行目から変数 C に格納(代入)されている内容を表示します。
例えば、C に 38 が、F 100.4 が格納されている時、以下のように表示されます。

16桁x4行の画面
°C          
°F       
                
                
        
       6桁目

実際の表示は以下のようになります。


1:°C 38
2:°F 100.4


こうしてみると、数値の後ろに単位(°C や °F)を表示したくなります。
そこで、Locate コマンドを使って、そのように表示を変更してみます。

"1:      °C" (スペース11個)
"2:      °F" (スペース11個)
Locate 4,1,C
Locate 4,2,F

16桁X4行の画面
        °C  
     °F  
                
                

TC2new-4 

この方が、自然な感じになります。

ここまでで、TC2 のプログラムをまとめます。

プログラム TC2
"1:°C"
"2:°F"
"INPUT MENU N°"?→M

Cls
If M=1:Then
"°C"?C
(9÷5)C+32→F
Else If M=2
Then
"°F"?F
5(F-32)÷9→C
IfEnd:IfEnd

Cls
"1:"
"2:"
Locate 4,1,C
Locate 4,2,F
Locate 13,1,"°C"
Locate 13,2,"°F"



TC2 を修正した目的は、複数の結果を表示させることでした。2つの温度を表示できたので、これを3つに増やすのは簡単です。



TC2 のプログラムを改造して、摂氏、華氏、絶対温度を換算するようにします。このプログラムを TC3  とします。

絶対温度を格納(代入)する変数を K とします。絶対温度 K は 摂氏温度 C と次の関係にあります。

C+273.15=K

或いは、

K-273.15=C

換算には、これらの式を使います。


さて、いきなり結論! 絶対温度を追加した換算プログラム TC3 を以下のようにしました。追加した部分を赤文字で示します。

プログラム TC3
"1:°C"
"2:°F"
"3: K"
"INPUT MENU N°"?→M

Cls
If M=1:Then
"°C"?C
(9÷5)C+32→F
C+273.15→K
Else If M=2
Then
"°F"?F
5(F-32)÷9→C
C+273.15→K
Else If M=3
Then
"K"?K
K-273.15→C
(9÷5)C+32→F

IfEnd:IfEnd
IfEnd

Cls
"1:"
"2:"
"3:"
Locate 4,1,C
Locate 4,2,F
Locate 4,3,K
Locate 13,1,"°C"
Locate 13,2,"°F"
Locate 13,3," K"




プログラム TC3 の説明

メニュー選択
"1:°C"
"2:°F"
"3: K"
"INPUT MENU N°"?→M


赤文字部分を追加しただけです。メニュー選択では、1、2、3 のいずれかを入力することになります。
なお、追加した部分で、K の前にスペースを1つ入れて、単位のアルファベットが揃えています。

16桁x4行の画面
°C            
°F            
 K            
                

?(入力)命令による入力待ちになり、プログラムはここで一旦停止して、以下のような表示になります。

TC3-7 


メニュー番号に応じた換算
Cls
If M=1:Then
"°C"?C
(9÷5)C+32→F
C+273.15→K
Else If M=2
Then
"°F"?F
5(F-32)÷9→C
C+273.15→K
Else If M=3
Then
"K"?K
K-273.15→C
(9÷5)C+32→F

IfEnd:IfEnd
IfEnd


M=1 つまり摂氏温度入力時は、華氏温度に加えて絶対温度を計算します。
M=2 つまり華氏温度入力時は、摂氏温度に加えて絶対温度を計算します。
M=3 つまり絶対温度入力時は、摂氏温度と華氏温度を計算します。
これらの計算を追加しています。


ところで、M の値による分岐処理を行う If 構文は、If が3つ使われているので、IfEnd も同数の3つ必要です。M=3 の時の Else If を1つ追加しているので、IfEnd も1つ追加しています。

If M=1:Then
[計算]
Else If M=2
Then
[計算]
Else If M=3
Then
[計算]
IfEnd:IfEnd
IfEnd


さて、この If 構文の構造は、上のような色分けで分かると思います。

赤のIf / Then / Else / IfEnd が一番外側にあって Else の中の処理に、緑の If / Then / Else / IfEnd が入っていて、さらに緑の Else の中の処理に、青の If // Then / IfEnd が入っています。

以下のようにスペースを入れて記述するとエラーになりますが、敢えてこのように書くと、3つの If 構文の入れ子構造が分かると思います。、

If M=1:Then
[計算]
Else

  If M=2:Then
  [計算]
  Else

    If M=3:Then
    [計算]
    IfEnd

  IfEnd
IfEnd


但し、プログラムを書くたびに、このような入れ子構造を意識するのは面倒です。単純に If の数と IfEnd の数が同じになるようにするだけで良く、どの If と どの IfEnd が対応するかまで考える必要はありません。


結果表示
Cls
"1:"
"2:"
"3:"
Locate 4,1,C
Locate 4,2,F
Locate 4,3,K
Locate 13,1,"°C"
Locate 13,2,"°F"
Locate 13,3," K"


摂氏温度 38 ℃を入力した時、F100.4K311.15 になるので、その時の表示は以下のようになります。

16桁X4行の画面
        °  
 .    °  
 .      
                

TC3-1 

この表示を行った後、プログラムは終了します。

ところで、COMPモード[FILE] キーによる Prog List から TC3 を実行すると、プログラムが終了しても、[EXE] キーを押すことで同じプログラムが再起動するので、TC3 を繰り返し実行できます。この場合、プログラムを終了させて、COMPモードの画面に戻るには [AC] キーを押します。


以上で、摂氏温度、華氏温度、絶対温度 の換算プログラムが一応完成しました。

?(入力)命令→(代入)命令Cls コマンドLocate コマンドだけでも、実用的な換算プログラムができました。温度換算以外にも、長さや重さなどの換算プログラムを作ってみると面白いと思います。



ところで、このプログラムにはチョット気になる点があります。

普通に電卓を使ったり、他のプログラムを実行させた後に、今回のプログラムを使うと妙な表示になることがあります。

TC3 を起動すると、以下の画面になります。

TC3-2 

そしてメニュー選択では、1、2、3 のいずれかを入力します。摂氏 38° と入力するつもりが、摂氏入力のための 1 と、温度の 38 を一気に入力、つまり 138 と入力してしまうことがありました。メニュー選択で 1~3 以外の数字を入力したわけです。

すると、以下のような表示になり、異常に気付きました。

TC3-3 

これは、どう考えても換算値として異常ですのでバグと言えます。正しく入力しないことが原因なのは確かです。自分で作って自分で使うならば、使い方に気をつければ良いので、気にしないでも良いのかも知れません。

但し、このバグの原因は知っておいた方が良いでしょう。次回はバグの原因と修正について説明するので、一度ご自分でデバッグに挑戦してみてください。


自分で使うだけでは、大した問題にならない今回のバグも、原因を探してそれを修正する経験が、プログラミングの理解を深めると思います。





つづく...

Casio Basic入門41 / 目次




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ

 


keywords: fx-5800PCasioBasic、入力ボックス, プログラミング入門プログラム関数電卓、温度換算

リンク集 | ブログ内マップ



関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

楽屋裏 - Casio Basic超入門

楽 屋 裏
e-Gadget

2015/01/31
更新: 2015/02/07

最近 fx-5800P の実売価格が下がってきて 5,000円台になる気配です。益々入手しやすくなっています。

そこで、fx-5800P を買ってきて、初めてプログラムを作ってみようというケースを想定した Casio Basic 超入門 を始めてみることにしました。

先ずは、、fx-5800P でプログラムを作るための操作方法について、できるだけ分かりやすく説明することを試みます。
そして、旧来の 入力/出力命令の使い方からスタートしてみることにしました。

旧来の入力/出力命令が分かりやすいのか、Locate / Getkey の方が分かりやすいのか、ここが悩みどころです。

Casio Basic の旧来の命令は、多くの機能を内蔵しているので、記述はシンプルですが、奥の深いところがあります。一方、典型的な Basic コマンドである LocateコマンドやGetkkeyコマンドの方が、私には明示的で分かりやすいように思うわけです。

ところで、Getkey を使うにはループを併用する必要があり、ループはプログラミング学習における敷居になっているらしい、と言う話が以前からあるようで、私はたまたま最近知りました。
 ⇒ 60%の人はプログラミングの素養がない
 ⇒ プログラマの適正検査

ならば、Getkey に加えて、入力待ち機能を持つ GetkeyWait があれば敷居が下がる筈です。

それはともかく、旧来の入力/出力命令は、表現はシンプルですが、その動作は意外に複雑であり、使いづらい面もあります。尤も、これは私の感覚です。しかし例えは、Casio Basic 旧来の入力命令は、入力待ちの機能が内蔵されており、ループを使う必要がありません。そこで、仮にループの理解が無くても、この旧来の入力命令は理解しやすい可能性があるわけです。

一方、Casio Basic を紹介しているプログやサイトでは、旧来の命令を利用した説明やプログラム例を多く見受けます。当ブログの Casio Basic 入門の最初に紹介しているような Getkey を使いこなす事例をあまり見ません(調べ方がまだ足りないのかも...)。これは、旧来の命令の方が分かりやすいと感じる人が多いことの反映かも知れません。

そこで、改めて旧来の命令を使ったプログラムを色々と検討してみました。その動作を正しく理解すれば、少ない記述量で所定のプログラムを作れることが分かってきました。当然制限はありますが、入力→計算→出力 を繰り返すプログラムなら、確かにシンプルに作れます。

このようなことを考えた結果、Casio Basic入門38から、旧来の命令を使って、みかけは超シンプルなプログラム作成からスタートし、徐々に改造してゆく内容を試みます。


[2015/02/07 更新]
現在のところ、Casio Basic入門38~39 まで公開したところです。旧来の命令を使いこなすことをテーマにしています。私自身、計算を繰り返す簡単なプログラムなら、旧来の命令が結構使えることを再認識しています。

但し、やはり構造化Basic である Caso Basic の真価は、旧来の命令以外のところにあると思っていて、これの良さを伝えたいと言う思いはさらに強くなっています。

面白いことに、これらのエントリーへのアクセス数が、Casio Basic入門1~8 へのアクセス数と同等になっていて、特に Casio Basic入門3~8 は、GetkeyLocate の使いこなしをテーマにしています。これが何を意味しているのか、とても興味深いです。

さらに、旧来の命令の使いこなしをご覧になっている方のうち、無視できない数の方が fx-9860GII のエントリーも同時にご覧になっているのも、興味深い結果です。





応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


keywords: fx-5800PCasioBasic換算プログラムプログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ
関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

Casio Basic入門39

Casio Basic(超)入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

最終: 2015/06/12


 4. CasioBasicを使ってみる(続き)


Chapter 7  - 初級

前回: Casio Basic入門38


◆ Chapter 7 の目標: ゼロからのプログラム作成と機能追加

前回は、摂氏温度を入力すると華氏温度を表示するプログラムを作りました。
?(入力)命令が持つ多彩な機能により、たった2行のシンプルなプログラムとなりました。

奥の深い?命令

1)
 入力: 数値を入力させ
2) 計算: 計算して
3) 出力: 結果を表示する

といったプログラム作成には、役立つことが分かります。

今回は摂氏から華氏の換算だけでなく、逆の華氏から摂氏を換算する2つの機能を持つプログラムに改造してみます。



Chapter 7-2
同様の機能を追加する

前回作った、摂氏から華氏への換算プログラムは以下でした。

”°C"?C
(9÷5)C+32


同様にして、華氏から摂氏への換算プログラムを作ってみます。

華氏温度を入力させるには、" " (出力)命令?(入力)命令を使って、以下のようにします。

"°F"?F

ここでは、入力された華氏温度を変数 F に格納(代入)しています。

次に、華氏温度 F から摂氏温度 C を得るには、以下の計算を行います(前回最後に紹介しています)。

C = 5(F-32)÷9

従って、華氏温度を入力させ、摂氏温度を表示させるプログラムは、以下になります。

"°F"?F
5(F-32)÷9



では、この新しいプログラムを、プログラム名 TC2 として、実際に作ってゆきます。

前回を参考にして、Program Menu 画面を表示しましょう。

Program Menu 

ここで [1] (1:NEW) を選び、ファイル名入力画面に切り替えます。

File Name 1 

ここで、プログラム名 TC2 を入力します。File Name? では、最初はアルファベットモードになっています。画面上部に A アイコンが表示されているので、アルファベットモードだと分かります。ここで、[2] (T) [°’”] (C) と入力した後、[ALPHA] を押してアルファベットモードを解除し、[2] を入力します。

TC2_FileName 

確定するために、
 [EXE] を押します。

すると、File Mode 画面に切り替わります。

File Mode 

ここで、 [1] (1:COMP) を選びます。

すると、何も表示のない画面に切り替わります。画面上に PRGM と表示されていて、この画面でプログラムの入力や編集を行います。

Program Input 

プログラム編集画面で、今回のプログラムを入力してください。

"°F"?F
5(F-32)÷9


1行目を入力したら、[EXE] キーを押して改行し、2行目の入力を始めます。

ここで、" を入力するには、
[ALPHA} [√□] ("
の順に入力します。

次に、°F の ° を入力するには、

[FUNCTION] キー
[5] キーで 5:ANGLE 選択
[1] キーで 1:° 選択

の順に入力します。

[FUNCTON] キーで FUNCTIONメニューが表示され、

Functionメニュー 

ここで、[5] (5:ANGLE) を選ぶと、ANGLEメニューが現れます。

Angleメニュー 

[1] (1:°) を選ぶと、° を入力できます。


次に、F を入力するには、
[ALPHA] [tan] (F) 
の順に入力します。


を入力するには、

[FUNCTION] [3] (3:PROG) [1] (1:?)

の順に入力します。

TC2_src 

上の2行のプログラムを入力し終わったら、[EXIT] キーを押します。すると、Prog Edit 画面に切り替わります。

TC2_Prog Edit 

ここで、TC2 にカーソルがきているので、[EXE] を押せば、再びプログラム編集画面になります。Prog Edit 画面に戻り、ここでさらに [EXIT] キーを押すと、Program Menu 画面に戻ります。今どこに居るのか分からなくなったら、[EXIT] を何度か押せば、最後には Program Menu 画面に戻ります。

Program Menu 



TC2の実行

さて、今入力したプログラム TC2 を実行しましょう。

Program Menu 

Program Manu 画面で、[2] (2:RUN) を選ぶと、Prog List 画面に切り替わります。

TC2_Prog List @ ProgMode 

ここで、カーソルが TC2 に合っていると思います。カーソルは矢印キー [▼][▲] で動かせます。

実行したいプログラム (TC2) にカーソルを合わせて、[EXE] キーを押せば、そのプログラムが実行されます。

では、実行しましょう。

TC2-1 

2行目の右端に数値が表示されていますが、前回説明したように、変数 F に格納されている値が表示されています。ここで、100 と入力しましょう。

TC2-2 

この入力を確定するために [EXE] を押すと、

TC2-3 

右下に 37.77777778 と表示されました。これが摂氏温度です。

このプログラム TC2 は、°F? と表示された時に華氏温度を入力すれば、摂氏温度を表示します。?(入力)命令の仕様で、出力は行の右端に表示され、入力した数値は行の左端に表示され、分かりやすくなっています。

ここで、[EXE] を押すとプログラムが終了して、Prog List  画面に戻ります。

TC2_Prog List @ ProgMode 

プログラムを編集するには、ここで [EXIT] を押し、Progrm Menu 画面に戻ります。

Program Menu 


もう1つのプログラム実行方法

[EXIT] キーを(何度か)押して、Program Menu 画面に戻りましょう。

Program Menu 

そして、[MODE] [1] (1:COMP) の順に押して、COMPモード(普通の電卓の画面)に戻します。

Compモード 

ここで、[FILE] キーを押すと、Prog List 画面に切り替わります。

TC2_Prog List @ CompMode 

この画面は、COMPモードでの Prog List なので、画面上部に PRGM の表示がありません。

さて、Prog List 画面では、自動的にアルファベットモードになっています。画面の左上に小さな A アイコンが表示されているので、アルファベットモードであることが分かります。ここで、[2] (T) を押すと、T で始まるプログラム名の最初のプログラムが一番上に表示され、カーソルが乗っています。もし T で始まるプログラムがなければ、アルファベット順で T の次で始まるプログラムが一番上に表示されます。既に TC2 を作っているので、TC2 にカーソルを合わせてから [EXE] キーを押すと、TC2 が起動されます。

TC2-1 

ここで、華氏温度 100 を入力し、
 
TC2-2 

[EXE] で入力確定すると摂氏温度が表示されます。

TC2-3 

ここまでは、上記の PROGモード での動作と同じです。

上の表示を行ったままプログラムは終了します。今は、COMPモードで [FILE] キーで現れる Prog List  から実行しているので、プログラム終了後 [EXE] を押すと、同じプログラムが起動します。こうやって繰り返しプログラムを実行できて便利です。

TC2-1 

実は、COMPモード[FILE] キーによる Prog List からプログラムを実行する時、COMPモード

Prog "TC2"

が実行されています。プログラム呼出コマンド Prog が関数のように使えるようになっています。試しに、COMPモードで上記の1行を入力してから [EXE] キーを押してみてください。

Prog コマンドを入力するには、[SHIFT] [FILE] (Prog) とキー入力します。その後、"TC2" と、" " を含めて入力します。そして、これを実行するために [EXE] キーを押すと TC2 が起動することを確認してください。 

プログラムが終了しても、COMPモードの画面には、上記の Prog "TC2" が残っているので、[EXE] キーを押すだけで TC2 が再起動するわけです。

Casioのプログラム電卓の中で、COMPモードでプログラム呼び出しコマンド Prog を関数のように使えるのは、fx-5800P だけです(fx-FD10 Pro でも COMPモードからプログラムを呼び出せるようですが、実際に確認していませんので詳細は不明です)。



以上で、摂氏から華氏への換算と逆方向の華氏から摂氏への換算の計算部分ができました。

それでは、1つのプログラムで 1) 摂氏から華氏への換算、と 2) 華氏から摂氏への換算を選んで実行できるプログラムを作ってみます。これが今回の目標です。

既に、それぞれの換算部分は出来ているので、プログラムの最初で、
 1) 摂氏から華氏への換算
 2) 華氏から摂氏への換算
のどちらを行うのかを選択させるメニューを作り、どちらか決まったら既に作ったプログラムを走らせるようにします。

例えば、以下のようなメニュー表示を作ってみます。

TC2 new-1 

この部分のプログラムは以下のようになります。

"1:°C"
"2:°F"
"INPUT MENU N°"?→M


1行目と2行目は、単に表示を行うだけです。3行目はメニュー番号を入力させて、入力値を変数 M に代入しています。

詳細をみてゆきます。

" " は、出力命令です。" " で囲んだ文字列を表示します。
 ⇒ Casio Basic コマンドリファレンス - " " (出力)命令

" " 命令で表示される行は、内部管理されているカーソル行です。
プログラムの最初、或いは Cls コマンドの直後の " " 命令では、内部カーソル行は1行目です。
その後、" " 命令が実行されるたびに、内部カーソル行が改行されます。

従って、

"1:°C" 

は、プログラムの冒頭なので、内部カーソル行である1行目に表示され、内部カーソル行が改行され2行目になります。

次の、

"2:°F"

は、この時点での内部カーソル行である2行目に表示され、内供カーソル行が改行され、3行目になります。

Casio Basic では区切り文字 : が使えます。区切り文字は、複数のコマンドを1行に並べて記述する時に使います。

"1:°C"
"2:°F"


と記述する代わりに、区切り文字を使って、

"1:°C":"2:°F"

と書くこともできます。ここで注意して欲しいのは、区切り文字を使っても表示では改行されることです。改行は " " (入力)命令が持つ機能です。従って、区切り文字を使って1行に記述したとしても、改行されて表示されます。区切り文字は、単に1行に記述するためだけのもので、それ自体何の命令も行いません。

さて、上の2行が実行されると、カーソル行は3行目に移ります。そして、プログラム3行目は、入力命令? を付加した書式です。

"INPUT MENU N°"?→M

 ⇒ Casio Basic コマンドリファレンス - ?(入力)命令

これが実行されると、画面には

INPUT MENU N°?

と表示され、入力待ちになります。数値を入力し [EXE] で確定されると、入力値が変数 M に代入(格納)されます。
なお、?命令 を付加した書式では、入力値を代入する変数 M の値を表示しません(前回参照)。

改めて、以上をまとめると、

"1:°C"
"2:°F"
"INPUT MENU N°"?→M


を実行すると、以下の画面表示になります。

TC2 new-1 

ちなみに、 は、No. と同じ意味の表記で、日本ではあまり見かけないのですが、欧米では使われます。今回は1行に収めたいのでこのような表記を使うことにします。
INPUT MENU N° は、「メニュー番号を入力してください」と言う意味になります。

従って、ここでは [1][2] を入力することになり、メニュー番号に応じて以下の流れで処理を行います。
・メニュー番号1を選ぶと変数 M には 1 が格納され、摂氏から華氏への換算を行う。
・メニュー番号2を選ぶと変数 M には 2 が格納され、華氏から摂氏への換算を行う。

変数 M の値に応じて処理を分岐するには、If 文を用います。If 文について詳しくは、次のコマンドリファレンスを参照してください。
 ⇒ Casio Basic コマンドリファレンス - If 文


さて、メニューで選択した変数 M の値に応じて、Ifを使った分岐処理を、以下のようにします。

If M=1
Then
<摂氏から華氏への換算>
Else If M=2
Then
<華氏から摂氏への換算>
IfEnd
IfEnd


プログラムは、上から下へ順に実行されるのでした。
命令やコマンドを改行する代わりに区切り文字 を使って1行に書くこともできます。但し、:記号の前後にスペースを入れるとエラーになるので、スペースを入れてはいけません。

上のプログラムの 最初の2行最後の2行 :記号 (区切り文字) を使って以下のように書き直せます。

If M=1:Then
<摂氏から華氏への換算>
Else If M=2
Then
<華氏から摂氏への換算>
IfEnd:IfEnd


ところで、:記号を入力するには、

[SHIFT] [√□] ()

と続けて入力します。

青文字で示した各換算処理は、既に作っている内容を適用します。

摂氏から華氏への換算
既に作っている次のコードを使います。
"°C"?C
(9÷5)C+32


華氏から摂氏への換算
これも既に作っている次のコードを使います。
"°F"?F
5(F-32)÷9



※ ”コード”とは?
プログラムの具体的な記述内容をコード、あるいはプログラムコードと言います。
プログラムを書くことをコーディングなどと言うこともあります。


以上をまとめると、プログラム TC2 は以下のようになります。

プログラム TC2
"1:°C"
"2:°F"
"INPUT MENU N°"?→M

Cls
If M=1:Then
"°C"?C
(9÷5)C+32
Else If M=2
Then
"°F"?F
5(F-32)÷9
IfEnd:IfEnd


ここで、Cls を追加しました。


メーニュー表示後、一旦 Cls コマンドで画面表示を消去し、内部カーソル行をリセットして1行目に戻します。fx-5800Pの取扱説明書には内部カーソル行に関しては、全く説明されていません。
 ⇒ Casio Basic コマンドリファレンス - Cls

Cls の効果を確認するために、上記の Cls を追加せずにプログラムを実行してみてください。表示がおかしくなることが分かると思います。


入力が終わったら、[EXIT] を2回押して、Program Menuへ戻ります。

Program Menu 

次に、[MODE] で モードメニューを表示させ、

Modeメニュー 

[1] (1:COMP) で、COMPモード(普通の電卓の画面)へ切り替え、

Compモード 

ここで、[FILE] キーを押して、COMPモードでの Prog List を表示させ、TC2 を実行します。

TC2_Prog List @ CompMode 

すると、TC2 が起動し、先ずメニューが表示されます。

TC2 new-1  

摂氏から華氏への変換を行いたい場合は、[1] を入力

TC2 new-2 

[EXE] で入力を確定すると、摂氏から華氏への変換の画面が表示されます。

TC1-1 

既に作ったプログラム通りにに動作します。摂氏温度 38 を入力し、

TC1-2 

[EXE] で確定すると、

TC1-3 

華氏温度 100.4 が表示され、そのままプログラムは終了します。

COMPモードでプログラムを実行したので、[EXE] を押せば TC2 が再起動してメニュー画面が表示されます。

TC2 new-1 

ここで、[2] を押して、華氏から摂氏への換算を選ぶと、

TC2 new-3 

[EXE] で確定すると、

TC2-1 

ここで、華氏温度 100 を入力、

TC2-2 

入力確定のために、[EXE] を押すと、

TC2-3 

換算された摂氏温度が表示されたままプログラムが終了します。

[EXE] を押すと、同じプログラムが再起動して、メニュー画面が表示されます。

TC2 new-1 

プログラムを終了するには、[AC] キーを押しでください。



今回は、2つの温度単位の間の換算プログラムを作りました。温度だけでなく、例えばcmとインチなどの長さの換算や重さの換算など、一部を変更するだけで、様々な換算プログラムを作れます。

さて、温度の単位には、摂氏と華氏以外にも絶対温度があります。絶対温度は科学技術では不可欠な温度単位で、

[絶対温度] = [摂氏温度] + 237.15 

と言う関係があります。

次回は、3つの温度単位:摂氏温度、華氏温度、絶対温度の間の換算プログラムを作ってみます。



つづく...

Casio Basic入門40 / 目次




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ

 


keywords: fx-5800PCasioBasic、入力ボックス, プログラミング入門プログラム関数電卓、温度換算

リンク集 | ブログ内マップ



関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

楽屋裏 - Dsz によるループ脱出

楽 屋 裏
e-Gadget


2015/01/11 ポイントを整理するため修正
2015/02/01 カシオからの回答のまとめ

※ 本件に関する注記を Casio Basic 入門14 の最後に追加しています


以前、Do や While を使った2重ループで、内側ループを脱出するために Dsz 命令を使うとエラーになる、と言う問題を取り上げました。
 ⇒ 楽屋裏 - 多重ループの謎
 ⇒ 楽屋裏 - ループ脱出の問題(カシオの回答)


カシオお客様センターとやりとりをし、カシオ殿の回答にも多少の時間はかかっておりましたが、それ以上に私が中途半端なままにしておりました。そこで、一旦カシオ殿の回答をまとめて掲載致します。以前のコメント欄を追いかけて頂ければ、お分かりの方にはお分かりだと思うのですが、それではカシオ殿には申し訳ないので、改めて別エントリーとしました。

他の方からもコメントがあるように、カシオお客様センターは、時間がかかってもきちんと対応をしてくれます。


さて、問題の起点は、以下の2重ループで Syntax ERRORが出ることでした。

While 1
20→C
Do
Dsz C
LpWhile 1
WhileEnd


これに対して、カシオ殿の回答は、以下のものでした。

2重ループ構造という条件はございません。
Dsz/Isz/⇒で偽の場合に、次のコマンドをスキップするという
仕様のため、次の条件の場合にSynERRORとなります。
・条件1: DoやWhileを用いたループがあること
・条件2:ループ脱出に Dsz/Isz/⇒を利用すること
・条件3:Dsz/Isz/⇒ の次のコマンドが、LpwileかWhileEndであること

この期待しない動作については、制御のスタック管理において、古くからある Dsz / Isz / ⇒  と 後から実装された Do ループと While ループ で整合性がとれていないのではないか?と言う質問については、

ご指摘の通りでございます。従来のコマンドに慣れ親しんだユーザー様に配慮し、従来仕様をあえて残させて頂きました。

とのことでした。結果として現行 Casio Basic の内部実装通りの動作と言うことです。

これを反映させた具体的な対応策は、下記のようになります。カシオ殿の提示はIf 文を用いたものですが、私が敢えて ⇒ 命令を使って書き直しています(上の不具合条件に抵触しません)。

1) Dsz / Isz を用いて脱出するループに Do / While ループを使わず Lbl / Goto を使う方法

While 1
20→C
Lbl 0
C-1→C
C⇒Goto 0
WhileEnd



2) Do / While ループの脱出に Dsz / Isz の代わりに Break を使う方法

While 1
20→C
Do
C-1→C
C=0⇒Break
LpWhile 1
WhileEnd




さて、

これまでのところ、sentaro様により、以下の回避方法が提示されています。

While 1
20→C
Do
Dsz C
LpWhile 1
LoWhile 0
WhileEnd



私も、以下の回避方法を見つけております。

While 1
20→C
Dsz C
LpWhile 1
Goto 0:Lbl 0
WhileEnd


sentaro様の方法は、内側の Do ループのスタック制御が必ず行われるようにした自然な方法です。しかしこの方法は、Doループでは使えますが、While ループでは使えないと思います。一方、私が見つけた方法は Do / While ループのいずれでも使えるように見え、Goto の実装に深入りする方法です。

これらの方法は、たまたまうまく言っているだけの可能性があります。

さらに、下記のようなコードは、上記の異常動作の条件に合致しますが、これまで動作異常の経験がありません。

20→C
Do
Dsz C
LpWhile 1
[スタック制御を行う何かの処理]

これも、たまたまうまくいっているだけの可能性があります。その1つの例として、Goto 0:Lbl 0 だったと考えられます。


今回、外側のループに Dsz で脱出させてみたところ、上の対処療法では問題があることが分かりました。

例えば、

20→D
While 1
20→C
Do
Dsz C
LpWhile 1
LpWhile 0
Dsz D
WhileEnd


は、D が 0 になった段階で Syntax ERROR になります。

20→D
Do
20→C
Do
Dsz C
LpWhile 1
LpWhile 0
Dsz D
LpWhile 1


も、D が 0 になった段階で Suntax ERROR になります。

外側のループにも同じ対処療法を施すと、

20→D
Do
20→C
Do
Dsz C
LpWhile 1
LpWhile 0
Dsz D
LpWhile 1
LpWhile 0


これでは、Syntax ERROR の表示は出ませんが、D が 1 の状態で固まってしまい、先に進みません。Dsz でのループ脱出は、やはり本質的なスタック管理のエラーがあるようで、対処療法も効きません。

Dsz の実行速度は魅力的ですが、少なくとも、

D-1→D:D=0⇒Beak
WhileEnd


或いは

D-1→D:D=0⇒Break
LpWhile 1


といった記述で、Break を使うのが安全のようです。カシオが提示した対処方法には、If 文での Break でしたが、可読性や処理速度を考えれば、条件ジャンプ命令 ⇒ を使う方がマシなので、これを対処方法とします。


但し、今のところ、Do や While ループの脱出に Dsz を使い、上記のような対処療法(Goto 0:Lbl 0 の挿入)の結果、エラーや異常動作を経験していません。たまたまなのかどうか、今はそこに最大の興味が移っています。



[2015/02/01] カシオお客様センターからの回答

以下の質問をカシオお客様センターに投げかけました。

 A) 上記の Goto 0:Lbl 0 による対処方法の是非

 B) 上記の LpWhile 0 による対処方法の是非

 C) Do / While ループに比べて、制御構造が複雑になると Goto/Lbl ループが遅くなる理由 

 以上について、関連する Goto の内部動作について教えて欲しい。

その結果、Goto の内部動作に関する情報と共に、丁寧で貴重な回答が得られました。それを以下にまとめます。


Goto と その他のスタック制御を行うコマンドでは内部管理が異なっている。

Goto 以外の制御コマンドは、1本のスタックを使って、制御構文開始コマンドでスタックを1つ積み、制御構文終了コマンドででスタックを1つ破棄する。ここで積まれるスタックとスタック段数を"正式なもの"と呼ぶ。

Goto については、それが実行されると、先ずプログラムの先頭から対応する Lbl を検索し、見つからない場合はエラーになる。

対応する Lbl が見つかるまで、Goto は 他の制御コマンドも検索し、Goto 専用の仮スタックと仮スタック段数カウンタに記録する。
そして Goto に対応する Lbl が見つかると、その Lbl の仮スタック段数と、正式スタック段数を比較する。

正式と仮のスタック段数の比較;
(A) Goto 実行時の正式スタック段数が、Lbl の仮スタック段数よりも大きい場合は、正式スタック段数を段数の差だけ破棄する。
(B) Goto 実行時の正式スタック段数が、Lbl の仮スタック段数よりも小さい場合は、正式スタック段数を更新して、仮スタック段数と同じにする。

以上の内部動作の後、Lbl の位置までプログラム動作を飛ばす。


1) Goto 0:Lbl 0 による対処について
20→C
Do
Dsz C
LpWhile 1
Goto 0:Lbl 0


Goto 0 が実行される時、
LpWhile 1 がスキップされているので、正式スタック段数は +1
Goto 専用仮スタック段数は、Lbl 0までの検索で LpWhile 1 を見つけた時に 仮スタック段数が1つ戻されるので 0、つまり、Lbl 0 での仮スタック段数は 0

正式と仮のスタック段数の比較の結果、上記の(A)に相当するので、正式スタックを1段だけ破棄するので、正式スタック段数は 0 となり、正しく修正される。

つまり、Dsz C で制御構文終了コマンドがスキップされる場合でも、その後に Goto 0:Lbl 0 があれば、正常に修正される。


2) LpWhile 0 による対処について
20→C
Do
Dsz C
LpWhile 1
LpWhile 0


の場合、制御構文終了コマンド LpWhile 1 がスキップされても LpWhile 0 があるので、スタックが1段破棄される。
正式スタックが1本しかないので、LpWhile 0 の代わりに、WhileEnd、Next などスタックを1つ破棄するような他の制御構文終了コマンドがあれば、正常動作する。


20→C
Do
Dsz C
LpWhile 1
・・・
・・・
Retuen

このように、・・・ の部分で、LpWhie 1 を超えて前に戻るジャンプがなければ、Return で全てのスタックが破棄されるので、プログラムは正常動作する。


20→C
Do
Dsz C
LpWhile 1
Break
LpWhile 1


の場合、Break の後に制御構文終了コマンドが必要だが、それには LpWhile 1 など何でも良いことになる。


3) Goto / Lbl ループが他のループよりも大幅に処理速度遅くなる条件について
Goto / Lbl ループは、ループが回るたびに上記の Goto による仮スタック管理と正式スタックとの比較を行い、Do, While For ループでは、スタックに記録されたアドレスへジャンプする動作のみ。従って、制御構造が複雑になるほど Goto / Lbl ループが遅くなる。

さらに、Goto / Lbl ループでは、Lbl がプログラムの先頭から遠くなるに従って、動作が遅くなる。


例1      例2
Lbl 0     ・・・・
・・・・     ・・・・
・・・・     ・・・・
・・・・     ・・・・
・・・・     Lbl 0
・・・・     ・・・・
Goto 0   Goto 0


例1は、Lbl 0 がプログラム先頭にあり、検索時に最初にヒットするため、すぐにジャンプ処理ができる。

例2は、Lbl 0 に行き着くまでの間、制御構文の処理なども実施しながら検索していくことから、処理の負担がかなり大きくなり、その分処理時間も長くなる。


4) 他の Casio Basic バージョンへの適用について
今回説明した Goto の内部動作については、fx-5800P、fx-9860シリーズ、fx-CG20シリーズ、fx-FD10Pro など、カシオのプログラム関数電卓の殆どのモデルに当てはまる。


以上が、カシオによる回答をまとめたものです。

ここまでの情報を開示頂いたカシオ殿に、深く感謝致します。




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


keywords: fx-5800PCasioBasic換算プログラムプログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ
関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

最新記事
最新コメント
カテゴリ
C# (3)
検索フォーム
Visitors
Online Counter
現在の閲覧者数:
プロフィール

やす (Krtyski)

Author:やす (Krtyski)
since Oct 30, 2013


プログラム関数電卓は、プログラムを作り・使ってナンボ!

実際に触って気づいたこと、自作プログラム、電卓プログラミングについて書いています

おもしろい・役に立つならクリックしてください。励みになります。
にほんブログ村 IT技術ブログ 開発言語へ
にほんブログ村


人気ブログランキングへ


FC2ブログランキングへ


写真: 「4駆で泥んこ遊び@オックスフォード郊外」

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

RSSリンクの表示
最新トラックバック
ブロとも申請フォーム

この人とブロともになる

QRコード
QR