Casio Basic入門34

Casio Basic入門
<目次>

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

最終更新:2015/01/25


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

Chapter 6

前回: Casio Basic入門33 を見る


◆ Chapter 6 の目標: プログラムを速くする
入力ボックスの改良と拡張

前回は、高速化したINPI Ver 2.0  を作りました。今回はこれを拡張して、0以上の小数に対応した入力ボックスを作ります。プログラム名は INP です。


1) INPI Ver 1.0 から Ver 1.2 への変更
※ 遅い処理を極量排除する。

 
2) INPI Ver 1.2 から Ver 2.0 への変更
※ プログラムの内部仕様(ロジック)変更を行い、その高速化を実感してもらう。


3) INPI Ver 2.0 を基に、INP Ver 2.0 を作るための機能拡張
※ 小数入力への対応方法を紹介する。

4) INP Ver 2.0 を基に、IN Ver 2.0 を作るための機能拡張
※ 負の数入力への対応方法を紹介する。




Chapter6-3
処理速度を意識して機能拡張する

前回作成した INPI Ver 2.0 (ファイル名: INPI)

INPI_Ver20d_src_1 


このプログラムを基に、小数入力(但し0以上の正の小数)ができるように拡張します。


小数点の扱い

先ずは、小数点のキー [・] を入力するところから、全ては始まります。

[・] キーが押されたことを検出するには、Getkey コマンドの戻り値が 26 かどうかを判定します。

先ず、INPI のプログラム構造を確認しておきます。

 [初期化処理]

 [初期表示]

 Do


 [キーコード取得]

 If (テンキーの場合):Then

  [テンキーの時の処理]

 Else If (DELキーの場合):Then

  
[DELキーの時の処理]


 IfEnd:IfEnd


 LpWhile K≠47


 [後処理]

 Return


これを拡張して、キーコード 26 の [・] キーが押された時の処理を追加すると、次のプログラム構造になります。


 [初期化処理 1]

 [初期表示]

 Do


 [キーコード取得]

 [初期化処理 2]

 If (テンキーの場合):Then

  [テンキーの時の処理]

 Else If (小数点の場合):Then

  [小数点の時の処理]


 Else If (DELキーの場合):Then

  
[DELキーの時の処理]


 IfEnd:IfEnd

 IfEnd

 LpWhile K≠47


 [後処理]

 Return


----------

赤文字で示したのは、今回追加する処理です。さらに  を付けたブロックは修正が必要と思われます。


小数点キーが押された時の処理

小数点以下の桁数(小数点自身を含む)を新しい変数 F で管理することにします。例えば、現在入力されている数が整数の時は F=0、小数点のみが入力されている時は F=1、小数部が1桁の時は F=2、小数部が2桁の時は F=3、小数部が5桁の時は F=6 とします。F の初期値は、0 とします。従って、[初期化処理 2] で、

0→C:0→F

としておきます。[初期化処理 2] は、キー入力ループで必要な変数の初期化を行うブロックです(ブロックと言っても1行で書けますが...)。

小数点キーが押された時の処理は、以下のようになります。[・] キーのキーコードは 26 なので、

Else If K=26
Then
If F=0:Then
Locate X+C,Y,"."
Isz C:Isz F
IfEnd


ところで、Else If  で If が1つ増えたので、LpWhile K≠47 の前に忘れずに IfEnd を1つ追加しておく必要があります。
 ⇒ Casio Basicコマンドリファレンス - If ~ Then ~ IfEnd




上のコードを1行づつ追いかけてシミュレーションしてみます。今、12 が入力されている状態で、小数点キーを押すと、上のコードが実行されます。これが実行された後は、

C=3
F=1
・ 表示は、12.

となることが確認できます。

3桁入力されているので、C=3 は正しく、小数点を含めて小数点以下の桁数 F=1 となり、画面表示は 12 の後に小数点が付加されているので、このシミュレーション結果から、この部分が正しく動作することが分かりました。

さらに、小数 [・] を入力する場合を考えます。1つの数に小数点が2つ以上あってはいけないので、小数点は1回しか入力できないようにすべきです。上のプログラムコードでは、小数点を追加する処理は、If F=0:Then ~ IfEnd の中に書かれています。1度小数点を入力すると、 F は 1 以上になるので、If F=0:Then ~ IfEnd の中を実行することはありません。これで、小数点が2つ以上入力されることを防いでいます。




テンキーが押された時の処理

INPI のプログラムの中で、テンキーが押された時に実行される部分は、以下のようになっています。

If (I≧1 And I≦9) Or K=25
Then
If C<D:Then
10Z+I→Z
Locate X+C,Y,I
Isz C
IfEnd

・・・
IfEnd

これを小数入力時に対応できるように修正してゆきます。





12. が入力されている状態で、3 をキー入力する直前の状態は、

C=3   (3桁入力されている)
F=1   (小数点を含んで小数点以下1桁)
Z=12.
・ 表示: 12.

となっていますので、ここで 3 を入力すると I=3 となります。この状態で Z の値を正しく更新するには、

12 + 0.3

となれば良いので、これを実現するためには、

Z+I÷10→Z   ・・・ (1)

であれば良さそうです。

(注意)加算 (+) や減算 (-) よりも 乗算 (X) や 除算 (÷) が優先されるので、この式は、
Z+(I÷10)→Z
と同じです。少しでもプログラムを速く動かすために、余計な処理を省きます。

さらに、12.3 が入力されている状態で 4 をキー入力する直前の状態は、

C=4   (4桁入力されている)
F=2   (小数点を含んで小数点以下2桁)
Z=12.3
・ 表示: 12.3

となっています。ここで 4 を入力すると I=4 となります。このとき Z の値を正しく更新するには、

12.3 + 0.04 

となる計算が必要で、

Z+I÷100→Z   ・・・(2)

であれば、Z が 12.34 となります。ここで、上の (1)(2) に出てくる除数 10 や 100 は、実は 10F とすれば良いだろう、と言う予測をしています。ところで、小数の桁数が増えるので、どこかで Isz F を行って F を1つ増やす(インクリメント)しないといけないのですが、これを (1) や (2) の前か後か、どちらで実行すれば良いのかが、計算をシンプルにして処理を速くするためのポイントです。結果として、Isz F(1)(2) の後で実行すれば、10100 の代わりに 10F を使えるので、これが最適だと分かります。

もし、Isz F(1)(2) の前に実行すると、10F ではなくて 10(F-1) を使う必要があり、F-1 という余計な処理が出てくるので、処理速度向上には良くないわけです。

10F をプログラムで表現するには、10^(F) となります。
具体的には、[1] [0] [x] [ALPHA] [F] [ ) ] の順にキー入力します。

そこで、入力値 Z を更新する処理は、

Z+I÷10^(F)→Z
Isz F


とすれば良いことが分かります。

整数入力の場合は、

10Z+I→Z

となり、これは既に作っています。

処理速度向上を目的にしているので、分数入力時か整数入力時かに関わらず、1つの式で処理できれば理想的です。ところが、これら2つの式を見比べても、効率的に1つの式にまとめられそうにありません。



そこで、整数入力時か小数入力時かによって、これらのいずれかを実行させるような条件分岐処理を行うことにします。整数入力時か分数入力時かは、F の値を見れば分かります。F=0 の場合は整数入力時、F=0 で無い場合は小数入力時を意味します。実は、このようになるだろうと予測して、変数 F の初期値を 0 にしたわけです。

さらに言えば、F0 かそうでないかの条件分岐には、F⇒ と言う条件ジャンプ命令か、If F:Then という記法を使え、これらは共に処理速度が速いことが分かっているので、整数入力時に F=0 とし、小数の桁数に応じて F をインクリメントすると決めたわけです。その結果、F は「小数点を含めた小数点以下の桁数」という、普通の数学とはチョット異なる定義になっています。

表示については、INPI Ver 2.0 と同様に

Locate X+C,Y,I 

とすれば良く、整数入力時と小数入力時で共通して使えます。Z の更新と表示を独立させるという、ロジック変更の効果がここに現れています(実は、予めこれを狙ってロジックを変更したのですが...)。


では、テンキー入力時の処理を、具体的に作ります。そこで、INPI Ver 2.0 のテンキー入力時の処理を以下のように修正します。

INPI Ver 2.0 のテンキー入力時の処理
If (I≧1 And I≦9) Or K=25
Then
If C<D:Then
10Z+I→Z
Locate X+C,Y,I
Isz C
IfEnd


INP Ver 2.0 のテンキー入力時の処理
If (I≧1 And I≦9) Or K=25
Then
If C<D:Then
If F:Then
Z+I÷10^(F)→Z
Isz F
Else

10Z+I→Z
IfEnd
Locate X+C,Y,I
Isz C
IfEnd


追加部分を赤文字で示しました。

赤文字の一番上の行は、If F:Then となっています。これは、If F>0:Then と同じですが、処理速度は If F:Then の方が2倍速いことが分かっているので、(予定通りに(^^;)処理速度が速くなる記法を採用します。
 ⇒ Casio Basicコマンドリファレンス - If ~ Then ~ IfEnd 
 ⇒ fx-5800P:変数アクセス、比較・論理演算、条件分岐の速度比較


DELキーが押された時の処理

INPI Ver 2.0 では、整数の最下位の数字を消せば良いので、10 で割ってから整数部を取り出すことで、Z の更新をしました。
例えば、1234 (=Z) と入力されている時、10 で割ると 123.4、 これの整数部を Int( ) 関数で取り出すので、

Int(Z÷10)→Z

としました。

小数入力時は、どうなるか?
例えば、今 12.34 (=Z) と入力されている時、最下位の 4 を消して、12.3 にしたいわけです。

Z (=12.34)10 倍して、123.4 とし、整数部を取り出して 123 にしてから、これを 10 で割ると 12.3 になります。具体的なコードで表すと、

Int(10Z)÷10→Z   ・・・(1)

となります。

12.34 と入力されていて、[DEL] キーを押す直前の状態は、

C=5   (5桁入力されている)
F=3   (小数点を含み、小数点以下3桁)
Z=12..34
・ 表示: 12.34

となっています。


シミュレーション 1

[DEL] キーで末尾を1桁減らすのですから、小数点以下の桁数も1つ減ります。そこで、先に F-1→F を実行してみます。
すると、F=2 となります。実は、(1) の2カ所に出てくる 10 は、上と同様に10F で処理できないかと予想しています。ところが、10F だと F=2 なので、100 になってしまい、ここは 10(F-1) (=10)でないとうまくゆきません。

F-1→F
Int(10^(F-1)Z)÷10^(F-1)→Z
Locate X+C,Y,">"
C-1→C


で良さそうで、確かに Z=12.3 となります。高速処理を目的にしているので、上と同様に (F-1) といった余計な計算をさせたくありません。ここで、10F を採用すると、上のテンキー入力所の処理では 10(F+1) が必要になり、両立が難しいことが分かります。どちらを取るか、の選択が必要です。

テンキーを入力時の高速化を優先させることにします。テンキー入力と [DEL] キーの頻度を考えると、テンキー入力が圧倒的に頻繁に実行される筈と考え、テンキー入力時の高速化を優先させる方が、入力時の体感も良くなると考えたわけです。


[DEL] キーによる削除処理での表示は、最下位の 4 は最上位から5桁目 (C=5) なので、4 が表示されているところに > を上書きします。

Locate X+C,Y,">"
C-1→C


で表示の更新を行ったのち、桁が1つ減るので C を1つ減らせば良いですね。


シミュレーション 2

続けて、[DEL] キーを押して、12.3 の末尾の 3 を消去するところをシミュレーションします。 
12.3 と表示されていて、[DEL] キーを押す直前には、

C=4   (4桁表示されている)
F=2   (小数点を含んで、小数点以下2桁)
Z=12.3
・ 表示: 12.3

となっています。

ここで、[DEL] キーを押した時の処理は、上と同様に、

F-1→F
Int(10^(F-1)Z)÷10^(F-1)→Z
Locate X+C,Y,">"
C-1→C


ここで、

Int(10^(F-1)Z)÷10^(F-1) = Int(1xZ)÷1 = 12 

となります。

なお、今 F=1 なので、10^(F-1) = 10(F-1) = 100 = 1 となります。何をゼロ乗しても、その結果は 1 と定義されているので、10のゼロ乗も 1 になり、これで正しいことがわかります。

さて、表示については、最上位から4桁目 (C=4) の 3 の上に > を上書きし、桁が1減るので、C-1→C としておきます。

これで、入力値 Z の更新と表示が正しく動作することがわかりました。


シミュレーション 3

続いてさらに [DEL] キーを押して、小数点を削除する際、その直前の状態は、

C=3   (小数点を含んで3桁表示されている)
F=1   (小数点を含んで、小数点以下1桁)
Z=12
・ 表示: 12.

となっています。

先ず、F-1→F が実行され、F=0 となります。小数点がなくなれば、F=0 になるのは正しい動作です。

続いて以下が実行されます。

Int(10^(F-1)Z)÷10^(F-1)→Z

F=0 なので、この計算は以下のようになります。

Int(10^(F-1)Z)÷10^(F-1) = Int(10F-1 x Z) ÷ 10F-1
= Int(10-1 X Z) ÷ 10-1 = Int(0.1 x Z) ÷ 0.1 = Int(1.2) ÷ 0.1
= 1 ÷ 0.1 = 10 
[Z=12 を代入]

となり、本来 Z = 12 となるべきところ、Z=10 となるので、これはマズイ!

今は、小数点を削除するだけで、Z の値は変化させる必要がありません。そこで、F=0 の時には、この計算を行わないようにすれば、良いので、この Z の更新処理を、

F⇒Int(10^(F-1)Z)÷10^(F-1)→Z

と変更すると、うまくゆきます。F=0 でない時はこの計算を実行し、F=0 の時は実行しません。これも、F をうまく定義したことの効用です。

F⇒ 命令の処理時間は 4.1ミリ秒、If A の処理時間は 6.2 道秒なので、F⇒ が 1.5 倍速いことが分かっているので、 命令を使っています。
 ⇒ fx-5800P:変数アクセス、比較・論理演算、条件分岐の速度比較 の 表参照

なお、F が負の数になると、上の F⇒ を使った Z の更新がおかしくなる心配があります。例えば、F = -1 の時は、上の Z の更新計算を実行することになり、計算結果がおかしくなりそうです。F を1つ減らす処理は、[DEL] キーが押された時の削除処理でしか行いません。そこで、F0 になれば、さらに1つ減らす処理を行わないようにすれば良いので、F の値の管理をきちんと行うことにします。





シミュレーション 4

さらに続いて [DEL] キーを押した時をシミュレーションします。
[DEL] キーをオス直前の状態は、以下のようになります。

C=2   (2桁表示されている)
F=0   (小数はなく、整数になっている)
Z=12
・ 表示: 12

この状態で、[DEL] キーで削除を行うと整数を削除することになるので、INPI Ver 2.0 で作った処理をそのまま適用すれば、問題ありません。小数からの削除を行うのか整数からの削除を行うのかは、F の値で条件分岐します(テンキー入力時の処理と同様です)。条件分岐した整数の末尾を1つ減らす処理で、F-1→F が含まないようにします。こうすれば、F0 より小さくなることはありません。

以上から、小数からの末尾削除については、以下のコードで良いことをシミュレーションから確認できました。

F-1→F
F⇒Int(10^(F-1)Z)÷10^(F-1)→Z
Locate X+C,Y,">"
C-1→C



整数からの削除と小数からの削除

さて、整数から最下位(末尾)の桁の削除する時と、小数からの最下位(末尾)の桁を削除する時では、Z の更新のために用いる計算が以下のように異なります。

整数からの末尾削除時は、

Int(Z÷10)→Z

小数からの末尾削除時は、

F⇒Int(10^(F-1)Z)÷10^(F-1)→Z

これらを、1つの式(処理)にまとめるのは難しそうなので、整数からの削除と、小数からの削除は、処理を分岐させることにします。

今入力されている数が整数か小数かは、F の値で判別できます。F=0 の時は整数、F>0 の時は小数なので、これを処理分岐の条件に使うことにします。


DEL キーを押した時の処理全体

さて整数のみを扱う入力ボックス INPI Ver 2.0 では、  [DEL] キーを押した時の処理は、以下です。

Else If K=34
Then
If C:Then
Int(Z÷10)→Z
C-1→C
Locate X+C,Y,">"
IfEnd


これに赤文字部分を追加して、小数対応すると、以下のようになります。

Else If K=34
Then
If C:Then
If F:Then
F-1→F
F⇒Int(10^(F-1)Z)÷10^(F-1)→Z
Else
Int(Z÷10)→Z
IfEnd
C-1→C
Locate X+C,Y,">"
IfEnd


Cつ減らす処理と、Locate コマンドによる削除の結果の表示処理は、修正なしにそのまま使えます。ロジック変更の狙い通りです。

なお上と同様に、If F>0:Then の代わりに、速度が2倍近い表記 If F:Then を使っています。 
 ⇒ fx-5800P:変数アクセス、比較・論理演算、条件分岐の速度比較 の表参照



上記以外の処理は、INPI Ver 2.0 と全く同じで問題ありません。今回作った0以上の小数入力に対応した入力ボックスを INP Ver 2.0 とし、プログラム名を INP とします。

INP_Ver20_src_1 



INP Ver 2.0 の仕様

高速化のため、Z の更新とリアルタイム表示を完全に独立させるようにロジックを変更した結果、INP Ver 2.0 は、入力仕様が Ver 1.2 と異なっています。

Ver 1.2 では、最上位に 0 や 小数点の入力をさせないようにするために余計は処理を加えていました。Ver 2.0 ではこの処理を省いています。

fx-5800P を普通の関数電卓として使う時、0123 や .123 と入力すると、そのまま表示されます。そして [EXE] キーを押せば 123 や 0.123 と表示されます。これは、fx-5800P の関数電卓としての仕様です。

INP Ver 2.0 でも同様で、例えば 0000123 や .0000123 と入力すると、そのまま表示されます。そして [EXE] キーで確定すると Z123 や 0.0000123 と格納され、メインルーチンに戻ります。

さらに、Z の更新とリアルタイム表示を独立させた結果、入力ボックスの桁数制限がプログラム上不要になりました。しかし、ハードウェアに依存して Locate コマンドによる制限は残ります。fx-5800P で使う場合は、Locate コマンドの制限が1行あたり16桁なので、入力ボックスの桁数は最大16桁に制限されます。実際の入力ボックスの桁数は、表示開始位置から右端までの桁数となりますので、最大16桁と言う言い方になります。fx-9860GII に移植して使う場合は、Locate コマンドの制限が1行あたり21桁なので、入力ボックスの桁数は最大21桁に制限されます。こうして、INP Ver 2.0 は、ソフトウェアとしての柔軟性と他機種への移植性が得られました。


使用方法

メインルーチンから以下の書式で呼び出します。

△→X:△→Y:△→D:△→E
Prog "INPI"
Z→▽


は、任意の数、但し使用機種の画面範囲内に収まるように設定する。
  参考 fx-5800P: 1≦X≦16、1≦Y≦4、X+D≦16


- X: 入力ボックス表示開始桁
- Y: 入力ボックス表示開始行
- D: 入力ボックス桁数
- E: 入力ボックスインジケータの選択
   E=2: 画面右下に <EXE>:ENTER と表示
   E=1: 画面右下に ▶E と表示
   E=(上記以外): インジケータを表示しない
- Z: 入力ボックスで確定した数値が代入される

入力ボックス内部では、上記5つの変数以外に、C、I、F、配列変数を用いています。以上9個の変数は、入力ボックスを呼び出すたびに代入されている数値が変更されます。メインルーチンでこれら変数を使っても問題はありませんが、これら9個の変数は入力ボックスを呼び出すたびに変更されても良い変数として使ってください。特に配列変数は、入力ボックス内で87個の領域確保を行い、メインルーチンに戻る前に領域解放を行いますので、それを念頭に置いてメインルーチンで使用してください。

なお、INPI に比べて、INP では、使う変数が1つ増えています(変数 F が追加)。


キー入力回数の測定

実際に前回と同じ方法で、INBOX TEST プログラムを使って、今回も入力応答性を実際に調べてみました。

比較対象は以下の2つのバージョン:

- INP Ver 1.2
INPI Ver 1.2 のロジックのまま拡張したもの。ソースコードは割愛します。

- INP Ver 2.0
今回作成した 新しいロジックの INPI Ver 2.0 を拡張したもの

なお、整数入力と小数入力では、処理を分岐させているので、整数入力と小数入力の2通りで比較測定を行います。


整数入力時の応答性

評価プログラム INBOX TEST を以下のようにします。
ここで、INP Ver 1.2 のプログラム名は INP12Ver 2.0 のプログラム名を INP とし、入力ボックスの桁数を 10→D により10桁にします。

プログラム名: INBOX TEST
Norm 2
0→Z:0→S:0→T:0→U
Locate 1,1,"1:"
Locate 1,2,"2:"
Locate 1,3,"3:"

Lbl 0

-1→M
Do
Getkey→K
While K=0
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M

Locate 1,4,"        "
  [スペース16個]

If M=1:Then
3→X:1→Y:10→D:2→E
Prog "INPI":Z→S
Else If M=2
Then
3→X:2→Y:10→D:2→E
Prog "INP12":Z→T
Else If M=3
Then
3→X:3→Y:10→D:2→E
Prog "INP":Z→U
IfEnd:IfEnd
IfEnd

Locate 1,4,"Z="

Locate 3,4,Z

Goto 0


比較は、メニュー2INP Ver 1.2メニュー3INP Ver 2.0で行います。

測定方法は、前回と同じ方法です。
それそれの入力ボックスを開いた状態で、タイマースタートと同時にいずれかのテンキーを押しっぱなしにします。そして10桁目に表示された瞬間にタイマーを止め、時間を読み取ります。

表1 整数入力時の応答速度比較
プログラムバージョン10桁入力所要時間1秒あたりの入力回数
INPI Ver 1.2 整数入力2.2秒4.5回
INPI Ver 2.0 整数入力1.4秒7.1回
INP Ver 1.2 整数入力2.6秒3.8回
INP Ver 2.0 整数入力1.6秒6.2回
※ この測定は、非常に個人差があるので、比較の意味しかありません。

参考までに、INPI Ver 1.2Ver 2.0 の結果も併記しました。

表1から、以下が分かります。
INP Ver 2.0 は、Ver 1.21.6 倍の入力応答性になる。
INP Ver 2.0 は、INPI Ver 2.0 に比べて、87% 程度の入力応答性になる。

実際に色々な数を入力してみると、かなり速く入力してもキーの取りこぼしが無く、十分満足できる応答性になっていると思います。


小数入力時の応答性

INBOX TEST では、D→11 として入力ボックスの桁数を11桁に設定します。そして、入力ボックスを開き、先に小数点を入力しておきます。すると残り10桁なので、タイマースタートと同時に、いずれかのテンキーを押しっぱなしにし、10桁目が表示された瞬間にタイマーを止め、時間を読み取ります。

なお、INP Ver1.2 は桁数制限があるので10桁までしか入力できません。一方で、新しいロジック(仕様)の Ver 2.0 は1行に収まる限り桁数の制限はありません。Ver 1.2十分遅いことが明かなので、INP Ver 2.0 のみを測定することにします。

そこで、INBOX TEST を以下のように、赤文字部分を変更します。そして、メニュー2 を測定に使用します。

プログラム名: INBOX TEST
Norm 2
0→Z:0→S:0→T:0→U
Locate 1,1,"1:"
Locate 1,2,"2:"
Locate 1,3,"3:"

Lbl 0

-1→M
Do
Getkey→K
While K=0
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M

Locate 1,4,"        "
  [スペース16個]

If M=1:Then
3→X:1→Y:10→D:2→E
Prog "INPI":Z→S
Else If M=2
Then
3→X:2→Y:11→D:2→E
Prog "INP":Z→T
Else If M=3
Then
3→X:3→Y:10→D:2→E
Prog "INP":Z→U
IfEnd:IfEnd
IfEnd

Locate 1,4,"Z="

Locate 3,4,Z

Goto 0



表2 小数入力時の応答速度比較
プログラムバージョン10桁入力所要時間1秒あたりの入力回数
INP Ver 2.0 整数入力1.6秒6.2回
INP Ver 2.0 小数入力1.8秒5.5回
※ この測定は、非常に個人差があるので、比較の意味しかありません。

参考までに、INP Ver 2.0 の整数入力の結果を併記します。

表2から、以下が分かります。
INP Ver 2.0 の小数入力時の応答性は、整数入力時の88%程度。

実際に色々な数を入力してみると、かなり速くキーを打っても、取りこぼしは発生せず、ストレスのない実用に十分耐える応答性が得られたと思います。


Lbl/Goto ループと Do/LpWhile ループ

INPI Ver 1.2 では、入力ボックスで入力が確定されるまでのループに Lbl/Goto ループを使っていました。一方、INPI Ver 2.0 を作る時は、Do/LpWhile ループに変更しました。プログラムが長く、複雑になると Lbl/Goto ループの処理時間が長くなることが経験的に分かっているので、このような変更を行いました。但し、INPI Ver 2.0 では、このループの変更により応答性の顕著な変化は見られません。

INP Ver 2.0 では、INPI Ver 2.0 に比べてプログラムの処理がより長く、制御構造がより複雑になったので、試しに Do/LpWhileLbl/Goto に換えて、応答性の比較測定を行ってみました。

表3 INP Ver 2.0 の Lbl/Goto と Do/LpWhile の応答性への影響比較
入力モードループ種別10桁入力所用時間1秒あたりの入力回数
整数入力
Lbl/Goto1.9秒5.2回
Do/LpWhile1.6秒6.2回
小数入力
Lbl/Goto2.1秒4.7回
Do/LpWhile1.8秒5.5回
※ この測定は、非常に個人差があるので、比較の意味しかありません。

表3から、INP Ver 2.0 では、Lbl/Goto ループによる応答性低下は、整数入力で 15%、小数入力で 16% になり、Do ループを用いた高速化の効果が明らかに現れました。

Goto 命令は ジャンプ先の Lbl を検索する際に、プログラムの一番最初から順に検索を行うことは、簡単な実験から分かっています。まだ詳細は分かりませんが、Goto 処理では内部的に何か特別な処理が行われている可能性、そしてDo/LpWhile ループでは、ジャンプ先検索が効率化されている可能性が考えられ、今回はその効果が明らかに出た事例と言えます。

ある程度長くて制御構造が複雑なプログラムでは、高速化を考える際には、Lbl/Goto ループを使わず、Do ループや While ループを使うべきであることが事実として明かです。その詳しい理由については、まだ不明ではありますが... 


プログラム高速化の指針

これまでのところ、Casio Basic プログラムを高速化するには、少なくとも以下の指針が有効だと言えます。

1) 比較演算、論理演算、配列変数へのアクセスを極力減らすこと

2) プログラムロジックの見直しによる、余計な処理の排除

3) ループには、Lbl/Goto ループを使わず、Do ループや While ループを用いること



今回作った INP Ver 2.0 を基に、次回から正負の小数入力ができるように拡張してゆきます。



つづく...

Casio Basic入門35 / 目次




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

人気ブログランキングへ


FC2ブログランキングへ



カシオプログラム関数電卓 FX-5800P-N カシオプログラム関数電卓 FX-5800P-N
(2006/09/22)
CASIO(カシオ)

商品詳細を見る



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

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



関連記事

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

コメントの投稿

非公開コメント

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

やす (Krtyski)

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


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

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

おもしろい・役に立つならクリックしてください。励みになります。

人気ブログランキングへ


FC2ブログランキングへ


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

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

この人とブロともになる

QRコード
QR