e-Gadget - プログラム関数電卓 2014年12月

Casio Basic入門33

Casio Basic入門
<目次>

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

最終更新:2015/01/25

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

Chapter 6

前回: Casio Basic入門32 を見る


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

前回は、INPI Ver 1.2 へのバージョンアップを行いました。今回は、さらに高速化して Ver 2.0 を作ります。


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-2
ロジックの見直しでプログラムを高速化する


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

INPI_Ver12_src_1 

ループ全体の論理演算と比較演算の個数と所要時間

Ver 1.0 (INPI10)
Ver 1.2 (INPI12)
処理種別 (時間)個数時間 (ミリ秒)個数時間 (ミリ秒)
倫理演算 (10ミリ秒)770330
比較演算 (11.5ミリ秒)141619103.5
合  計
231
133.5
※ 処理時間(ミリ秒)の絶対値は、必ずしも正しくなく、比較のための目安として使っています。


今回は、1つめの If (I≧1 And I≦9) Or K=25 の場合の処理に含まれる以下のコードに着目し、

C≠1 Or A≠25⇒Isz C
C=1⇒K→A


これらの処理を見直して、さらに高速化を試みます。

結論から言えば、これらの処理をほとんど削除できました。先ずは、今回作った Ver 2.0 のコードを Ver 1.2 と並べてみます。変更する部分は赤文字で示しています。

INPI_v12_v20_comparison.png 

Ver 1.2Ver 2.0 のループ全体の論理演算と比較演算の数をまとめてみます。

ループ全体の論理演算と比較演算の個数と所要時間

Ver 1.2 (INPI12)
Ver 2.0 (INPI20)
処理種別 (時間)個数時間 (ミリ秒)個数時間 (ミリ秒)
論理演算 (10ミリ秒)330220
比較演算 (11.5ミリ秒)10115780.5
合  計
145
100.5
※ 処理時間(ミリ秒)の絶対値は、必ずしも正しくなく、比較のための目安として使っています。

単なる目安としても、論理演算と比較演算の回数を減らすことで、応答性の大幅な向上(約50%向上)が期待できるわけです。


キー入力回数の測定

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

INPI バージョン10桁入力所要時間1秒あたりの入力回数
1.02.8秒3.5回
1.22.2秒4.5回
2.01.4秒7.1回

この測定は、非常に個人差があるので、比較の意味しかありませんが、Ver 1.2 に対してVer 2.0 の応答性は、実際に事前の推定通り約50% 向上したと言えます。最初の Ver 1.0 に対しては2倍の入力応答性が得られました。

実際に使ってみると、かなり高速化されたと感じると思います。



今回の Ver 2.0 では、論理演算と比較演算を減らすために、プログラムのロジック(仕様)を変更しています。それによって、今回着目している上記2行の部分から、論理演算と比較演算を完全に取り去り、Isz C のみにできました。


Ver 1.x のロジック

入力ボックスでは、主に2つのことを行います。

1) 入力操作に応じて、内容を表示する
2) 入力操作に応じて、結果を変数に保存する

Ver 1.0 では、計算して更新した値を変数Z に代入し、そのZ Locate コマンドで表示しています。入力結果と表示が常に同じであることが保証されるので、この方法を採用しました。

キー入力するたびに、何桁目を入力しているかをプログラムで管理しています。変数C がこれから入力する桁数を示し、C=0 は何も入力されていない状態、C=1 は1桁、C=2 は2桁入力されている状態を示します。

INPI は、10桁以上入力できない仕様にしていました。Z が11桁以上になると、fx-5800Pの仕様のため、Z を表示する際に 指数表示になり、桁数の管理ができなくなることが、その理由です。そこで、桁数の最大を 10 としていました。入力ボックスの表示桁数は変数D で管理しているので、D10 を超えると D=10 とするようにしています。

キー入力を進めてゆき、現在の桁数CD を超える場合は、それ以上入力できないように管理しています。[DEL] キーで消去する場合も、現在の桁数C を減らしてゆき、C=0 となれば、それ以上削除できないようにしています。

このように、変数C を用いた桁数の管理は、正常動作に必要です。


さて、例えば 001234 と6桁入力した場合、Z の値は1234 となり、桁数が2つ異なってしまい、桁数管理がうまくゆかなくなります。そこで、最初の桁(=一番左の桁)には、0 を入力できないようにしています。そのための処理が、今回着目した部分(下記)です。

C≠1 Or A≠25⇒Isz C
C=1⇒K→A


INPI を正負小数入力に拡張すると、小数点やマイナス記号も、最初の桁(=一番左の桁)に入力させないように抑制しなければならなくなり、小数点の位置や負号の有無の管理と併せて、この入力抑制処理がさらに膨らんで複雑になることが容易に想像され、実際に作ってみると、かなり複雑になってしまいます。

要するに、入力結果の数Z をそのまま表示させる方法を諦めて、他の方法に変更しなければ、処理をシンプルにして、論理演算や比較演算を減らすことができないと考えました。


Ver 2.0 のロジック

そこで、入力操作に応じた「表示」 と 「変数への保存」を独立させることにしました。

その結果、001234 と入力すれば、表示は 001234 となり、現在の桁数を管理する変数C には 6 が格納されます。そして、変数Z には 1234 と保存されます。変数Z を表示することを止めて、入力キーコードから変換したキーの数字をキー入力のたびに表示するようにました。

これにより、桁数管理の整合性をとるための、上記の2行の処理は不要になります。それに伴って、変数A を使うことがなくなり、変数 A を使うために、プログラムの最初で A→Z[1] とし、最後で Z[1]→A とする処理も不要になりました。 

さらに、このロジックでは、Locate コマンドを使った表示処理で、指数表示の影響を考える必要がなくなり、最大桁数の管理も不要になりました。必要なら fx-5800P の最大桁数16桁を入力ボックスの桁数にすることも可能になります。但し、INPI を呼び出す時に、プログラムによっては、最大桁数の管理を行う必要が出てきます。これは作るプログラム次第で考えれば良いので、入力ボックスのプログラムで考える必要はありません。

最初から、これを思いつけば苦労は無かったのですが、しかたありません。むしろ、不適切なロジックに皆さんを付き合わせてしまって、大変申し訳なく思っています。ハードウェア性能をうまく引き出せば、凝ったプログラムも可能になります。今回は、悪いお手本とそれを改善するところをご覧頂きたいと思います。



INPI Ver 2.0 プログラムの説明

個々の処理について、説明を加えました。赤文字で書いている処理については個別に説明します。

EngOff        [初期設定]:通常の整数表示のために EngモードをOff
0→Z
           [初期設定]:入力結果を代入する変数を 0 で初期化
87→DimZ
       [初期設定]:全てのキーコードを代入する領域確保
1→Z[35]:2→Z[36]
  [初期設定]:テンキーの数字とキーコードの関連付け
2→Z[37]:4→Z[21]
  [初期設定]:テンキーの数字とキーコードの関連付け
5→Z[22]:6→Z[23]
  [初期設定]:テンキーの数字とキーコードの関連づけ
7→Z[31]:8→Z[32]
  [初期設定]:テンキーの数字とキーコードの関連づけ
9→Z[33]
       [初期設定]:テンキーの数字とキーコードの関連づけ

If E=2:Then
           [初期表示]:入力モードインジケータ E=2の時
Locate 6,4,"<EXE>:ENTER"
  [初期表示]:このように表示
Else If E=1
           [初期表示]:入力モードインジケータ E=1の時
Then
Locate 15,4,"▶t"
        [初期表示]:▶ を表示させたいので先ずは▶t
Locate 16,4,"E"
         [初期表示]:これで ▶E と表示
IfEnd:IfEnd

For 1→I To D
      [初期表示]:指定桁数D だけ繰り返す
Locate X+I-1,Y,">"
   [初期表示]:指定座標(X, Y) から D桁だけ > を表示
Next
0→C
           [初期設定]:現在の入力桁を管理する変数C を 0 で初期化

Do
            [ループ]: LpWhile K≠47 との間のループ

Do
           [キーコード取得]:何かキーが押されるまでループが回る
Getkey→K
        [キーコード取得]:キ-コードを変数K に代入
LpWhile K=0
      [キーコード取得]:何もキーが押されない時ループ継続
Z[K]→I
          [キーコード取得]:キーコードを変数 I に代入, 1-~9以外は 0

If (I≧1 And I≦9) Or K=25
  [テンキーが押下時:数字を一桁ずつ得てZ再計算]
Then
If C<D:Then
     ⇒現在の入力桁 C が最大桁数 D 以上では何も処理しない
10Z+I→Z
       ⇒入力数を更新して変数Z に代入
Locate X+C,Y,I
    ⇒指定座標(X, Y) のXからC桁目に I を表示
Isz C
         ⇒桁数管理変数C を1つ増やす。C+1→C よりも Isz C が高速
IfEnd

Else If K=34
     [DELキーが押下時:数字を右から一桁ずつ削除してZ再計算]

Then
If C:Then       ⇒桁数管理変数C が 0 の時は何もしない ⇒ 削除しない
Int(Z÷10)→Z       ⇒Z を 10 で割った結果の整数部を得て、Z に代入
C-1→C         ⇒桁数が1つ減るので、現在の桁 C を1つ減らす、Dsz C 不可
Locate X+C,Y,">"   ⇒削除した数字の跡に > を表示
IfEnd
IffEnd:IfEnd

LpWhile K≠47
     [ループ] EXEキーが押されない限り Lbl 0 へ戻る


For 1→I To D-C     [後処理]:入力桁を示す >>>> を消去
Locate X+C+I-1,Y," "  [後処理]:入力数の1つ右から最大桁数までスペース表示
Next

If E=2:Then         [後処理]:入力モードインジケータ E=2の時
Locate 6,4,"      "    [後処理]:インジケータをスペース11個で上書き
Else If E=1         [後処理]:入力モードインジケータ E=1の時
Then
Locate 15,4," "        [後処理]:インジケータをスペース2個で上書き
IfEnd:IfEnd

0→DimZ            [後処理]:配列変数の領域を解放
Return
             [メインルーチンへ戻る]



INPI Ver 2.0 の使い方

メインルーチンにおいて、INPI を呼び出す直前に、必要な変数設定を行います。
- X: 入力ボックス表示開始のX座標 
- Y: 入力ボックス表示開始のY座標
- D: 入力ボックスの桁数 (最大入力桁数)
- E: 入力モードインジケータの設定
   ・E=2:  画面右下に <EXE>:ENTER と表示
   ・E=1: 画面右下に ▶E と表示
   ・E=0 あるいはそれ以外: インジケータの表示なし

[EXE] キーで入力確定すると、入力値が変数 Z に格納されて INPI が終了するので、メインルーチンでは INPI 呼び出し直後に Z を適切な変数に代入しておく。

例)
3→X:2→Y:6→D:1→E
Prog "INPI20"
Z→A


INPI では、上記の変数以外に、変数 CIK を使います。これら3つの変数に加えて上記の5つの変数は、INPI で使用され値が変わります。メインルーチンでは、これら5つの変数を使えますが、INPI を呼び出すたびに変更されても良い変数として使ってください。


INPI Ver 2.0 の入力桁数制限について

入力ボックスの桁数の制限は、Locate コマンドの制限に依存します。つまり、画面の桁数が16桁なので、最大16桁まで使えます。
但し、入力した数値をプログラムで計算に使う場合は、fx-5800P の計算精度に留意する必要があります。

1回の計算につき10桁目の誤差が±1となります。計算結果が10桁以上になると(Norm 2 指定の場合)指数形式になり、その場合は仮数部の最下位桁の精度が±1になります。一回の計算では、10桁未満であれば計算精度が保証されるわけですが、計算を繰り返す際に上記の桁数制限を受ける場合は、そこで誤差が発生します。

但し10桁の制限は、実はPCで使える開発環境でも、多くの場合同様ですから、fx-5800P に限った問題ではありません。この点は意外に認識されないことが多いのですが、その意味で fx-5800P は十分な精度を持っていると言えます。

なお、INPI では、プログラム内で敢えて桁数制限を設けないことにします。そもそも INPI を使って10桁の計算をすることは殆ど無いと思いますし、柔軟な仕様にしておく方が何かと良いと思うからです。

(注) INPI Ver 1.0 および Ver 1.2 では変数 Z をそのまま 表示させる仕様であったので、桁数制限が10桁でした。従って、入力桁数が10桁以上にならないように、プログラム内で制限をかけていました。Ver 2.0 では、この点がより柔軟になっています。


INPI Ver 2.0 での入力値 Z の更新方法と表示方法について

上のプログラムで、赤文字で示した部分が、本プログラムの一番重要なところなので、説明します。

Ver 2.0 では、キー操作ごとに入力値 Z を更新計算します。リアルタイム表示は変数 I を使い、Z を用いません。
これらの動作は、現在の入力位置 C と 最大桁数 D を用いて制御しています。

テンキー入力時の 入力値 Z の更新

[2] [0] [1] [4] と順次入力する場合をみてみます。

[2] キーを押すと、Z=2 となります。次に [0] で Z=20 とし、さらに [1] で Z=201[4] で Z=2014 としたいわけです。Z を10倍し、テンキーの番号 (変数 I )を加えれば、Z を更新できることが分かります。つまり、

10Z+I→Z

Z の更新計算となります。


DEL キー入力時の入力値 Z の更新

Z2014 の時、[DEL] キーを押ると、最下位の 4 を削除する仕様です。つまり、Z=201 としたいわけです。2014 から 201 にするには、201410 で割って、整数部を取り出せば良いので、

Int(Z÷10)→Z

が、Z の更新計算となります。


テンキー入力時の表示の変更

入力ボックスの表示開始座標は(X, Y)で、指定桁数(最大桁数)は、D です。そして、現在の入力桁を、C としています。テンキーの番号は変数 I です。

最初に [2] を押すと、最上位(一番左の桁)に 2 を表示する仕様です。入力した直後は、C=0 です。

入力ボックス1桁目表示直後 (C=0)
 X X+1X+2X+3X+4X+5
2>>>>>





Locate X, Y, I とすれば良いですね。そして、現在の入力桁 C はつ増やして(インクリメントして)、1 になります。

続いて  [0] を押すと、左から2桁目に 0 を表示したいので、表示桁は1つ右にズレます。表示行はそのまま同じです。

Locate X+C,Y,I

とれば、良さそうですね。

入力ボックス2桁目表示直後 (C=1)
 X X+1X+2X+3X+4X+5
20>>>>





表示後、C をインクリメントします。C+1→C とすれば良いのですが、Isz C とする方法もあります。前回紹介した各処理の時間比較の結果、Isz CC+1→C よりもかなり速いことが分かっているので、高速化が目的の INPI Ver 2.0 では、Isz C を採用します。

さらに、[1] キーを押すとき、

Locate X+C,Y,I
Isz C


で、うまくゆくことが分かります。

入力ボックス3桁目表示直後 (C=2)
 X X+1X+2X+3X+4X+5
201>>>





続けて、[4] キーを押すと、

Locate X+C,Y,I
Isz C


で、問題無いことが分かります。

入力ボックス4桁目表示直後 (C=3)
 X X+1X+2X+3X+4X+5
2014>>




そして、Isz C を実行して C4 となります。


DEL キー入力時の表示の変更

2014 と入力されている状態で、[DEL] キーを押すと、末尾の 4 を消去する仕様です。末尾の 4 を消去するには、4 > を上書きします。

2014 と入力されている状態では、C=4 となっています。そこで、先ず最初に C を1つ減らし(ディクリメントし) C=3 とした後

Locate X+C,Y,">"

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

入力ボックス表示 (C=3)
 X X+1X+2X+3X+4X+5
201>>>





さて、C のディクリメントの方法は、C-1→C とするか、Dsz C とする方法があります。高速化のためには、Dsz C が良いのですが、これだと問題があります。

Dsz C は、ディクリメント後 C0 になると、次の処理を飛ばして、2つめの処理までジャンプする命令です。入力ボックスを完全に消去する時、C=1 となっているので、この状態でディクリメントすると C=0 となります。すると Dsz C により次の処理を飛び越えてしまうので問題です。従って、ここでは C-1→C を採用します。

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



ループの見直し

Ver 1.2 では Lbl 0 ~ Goto 0 をループに使っていました。プログラムの制御構造 が複雑になると、Lbl / Goto をループに使うよりも Do / LpWhileWhile / WhileEnd ループを使う方がプログラムが速くなることが経験的に分かっています。プログラムが長くなるほど、その効果は大きくなります。実のところ、今回の INPI Ver 2.0 では、Lbl 0 ~ Goto 0Do ~ LpWhile K≠47 に変更しても、実際の測定では明かな差は出ていません。しかし、これより複雑な制御構造を持つプログラムでは、その差が出てくる可能性があるので(実際に差がでてきます)、今回は Do / LpWhile ループに変更しておきます。

※ 制御構造とは、プログラムを構成する命令やコマンドを実行する順序のことです。プログラムは通常上から下へ実行され、If 文や⇒命令、Dsz/Isz命令 による条件分岐、Goto/Lbl などの無条件分岐や Do/While/For 文などのループ処理、そして Prog コマンド によるサブルーチン呼び出しがある時だけ、この原則を破ってすぐ下の処理ではなくて、別のところへジャンプします。分岐やループの処理の無いプログラムは最も単純な制御構造を持っています。分岐やループ、サブルーチン呼び出しが多くなるほど制御構造が複雑になります。



INPI Ver 2.0 の仕様

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

Ver 1.2 では、最上位に 0 の入力をさせないようにしていましたが、このために余計な処理を加えていました。Ver 2.0 ではこの処理を取り去っています。

fx-5800P を普通の関数電卓として使う時、0123 と入力すると、そのまま表示されます。そして [EXE] キーを押せば 123 と表示されます。fx-5800P の仕様と同じで問題ない筈です。

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

さらに、Z の更新とリアルタイム表示を独立させた結果、入力ボックスのプログラム上の桁数制限が無くなりました、fx-5800P で使う場合は、Locate コマンドの制限が1行あたり16桁なので、入力ボックスの桁数は16桁に制限されます。fx-9860GII で使う場合は、Locate コマンドの制限が1行あたり21桁なので、入力ボックスの桁数は21桁に制限されます。こうして、柔軟性と移植性が得られました。


使用方法

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

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


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

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

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



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




つづく...

Casio Basic入門34 / 目次




応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ




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

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



関連記事

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

番外編 - プリンタ複合機

番外編 - プリンタ複合機
e-Gadget

2014年12月21日
2014年12月22日 追記
2015年08月07日 追記

[2015/08/07]: 結局こうなった...を一番下に追記しておきます。


10年以上使っていた HPのプリンタ複合機 Photosmart 3210a がついに壊れた(/_;)
肝心の印刷がうまくできなくなって、半年。プリンタがなくても困らないことに気がつき、これはちょっとした発見でした。しかしながら、年賀状印刷のシーズンを迎え、そのままというわけにも行かず、ついに買い換えました。

我が家のプリンタ複合機の事情は、当ブログ e-Gadget に大きな影響があります。e-Gadget で掲載するプログラム電卓の画面のスキャンが、買い換えにより出来なくなります。これはイタイ(/_;)

このHPの複合機を購入するとき、スキャナ機能にこだわりました。まさか電卓の液晶表示をスキャンするとは、購入当時は考えませんでしたが、本のスキャンの品質にこだわりました。当時の市場では、スキャナには2種類あり、センサがCCDのものとCMOSのもの(CIS)がありました。CCDタイプは高価になるものの、段差があっても綺麗にピントがあってスキャンできるので、私はCCDタイプにこだわったのです。その結果、電卓の画面のスキャンは問題無く綺麗にできました。

ところが、最近は普及価格のモデルでは、CMOS Image Sensor (CIS) タイプしか選択肢がありません。そこで、量販店で様々な複合機で、電卓画面のスキャンを試しました。電卓のスキャンを徹底的に試す私は、担当者には奇異に映ったことだと思いますが、私には切実な問題なわけです。

結果は、当然ながらまともにスキャンできるものは皆無でした。

そうなれば、あとはインクコストと、修理にならないための堅牢な作り、つまりはトータルの経済性を追求するのみ。結局、インク等の運用コストが安そうで、作りがしっかりしていそうな、Canon PIXUS MG7530 (A4複合機の最新モデル) に、落ち着きました。Canon機の樹脂の厚みが特段厚いわけでもないのですが、構造や機構がよく考えられていて、部材の脱着や差し込みなどが、余計な力を加えずスムーズにできるようになっているのは、さすがです。

購入後、ダメ元で 電卓画面のスキャンを試しましたが、液晶表示はガラス面から距離があるため、やはりピントが合わず...

残念!

それにしても、CANON機に標準添付されているスキャンソフトは、かなり酷いですね。HP機のスキャンユーティリティの完成度の足下にも及びません。

ばかでかい HP 機を、スキャナのためだけに置いておきたいのですが、それも難く、泣く泣く捨てるしかなさそうです。そして、今後の e-Gadget に影響が出そうです。デジカメを使った撮影環境を整える必要がありそうです。

CISスキャナでも、電卓の液晶をきれいにスキャンできる方法について、ご提案があれば是非ともお聞かせください。
或いは、スマホやデジカメを使って、映り込みや光源反射の無い綺麗な撮影を手軽にできる方法があれば、是非ともご教示ください。


[2014年12月22日 追記]
CCDセンサを搭載した小型のフラットベットスキャナを調べてみたところ、EPSON の GT-S640 が実売で¥7,500程度であることを発見。安いといっても、この価格。最後の手段としてとっておくことにして、お金のかからない良い方法を継続して探索することにします。


[2015年8月7日 追記]
やはりCCDセンサを使ったスキャナ機能は捨てるには勿体ないので、なんとか場所を確保してスキャナ機として使っています。プログラム電卓の液晶表示を綺麗にスキャンできるのは、e-Gadget 運用には不可欠です。



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ




keywords: プリンタ複合機e-Gadget

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

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

年末恒例、電卓すす払い

2014年12月20日

年末も押し迫ってきました。この時期は年賀状の準備に併せて、所有電卓のすす払いを行っています。


恒例の電卓すす払い

日常使い以外の電卓は、動態保存を目指しています。乾燥剤入りの箱から出してきて、清掃、動作確認、必要に応じて電池交換を行います。

My Calcs 

これらは、実際に新品として購入して、一度は日常使いをしたものばかりです。右下に写っている fx-995ES だけが例外で、カシオのスタンダード関数電卓の第三世代の最終型としての記念に購入したものです。2015年2月には 高精細液晶を搭載した fx-JP900 が発売予定で、これは第四世代のスタンダード関数電卓と言えます。
・第一世代: 最初の関数電卓
・第二世代: 数式通り入力タイプ
・第三世代: 数学自然表示タイプ
・第四世代: 高精細液晶タイプ
        ⇒ Casio fx-JP900


過去の名機レビュー

プログラム電卓は、今も昔も高価な製品なので、調べて納得してから購入すると言うのが通常です。2回だけ衝動買いをし、結果的に、最初は大ハズレ(fx-4500P)、2回目は大当たり(fx-5800P)でした。

今回は、ちょっと懐かしさもあって、記事にしてみようと思います。

FX-502P
FX-502P & Manual

これは、FX-502P 、一世を風靡した手帳サイズのプログラム関数電卓です。保証書には 1979年4月とあります。35年経った今でもきちんと動作します。生まれて初めて個人で所有した電卓が、いきなりこの機種でした。親に買って貰ったもので、当時は搭載されている関数全部が理解できませんでした(/_;)
昨年まであったプログラムライブラリがなぜだか見つからず、年末の大掃除での捜索対象です。人生で初めて作ったプログラム(反射ゲーム)はこの電卓で作ったものです。

 ⇒ FX-502P / 602P / 603P のプログラム

アセンブラのような言語で、最初は分かりにくいものでしたが、最近の Casio Basic には無い、間接ジャンプ、間接参照ジャンプといったまさにアセンブラのような命令があって、限られたプログラム領域やメモリで効率良く動作させる仕様です。まさに神のようなプログラムが多く発表されたものです。

FX-602P
FX-602P & Manuals 

FX-502P ではプログラムが保存しきれなくなったのでFX-602P を入手し、日常使いしていました。1984年6月19日の日付の保証書も残っていて、30年経った今でもきちんと動作します。プログラム言語は FX-502P とほぼ互換です。今でも FX-602P Page と言うサイトが残っていて、当時の "神プログラム" に熱狂した雰囲気を味わうことができます。

FX-502P や FX-602P は30年以上経てもなお健在、その品質の高さには驚きます。

FX-603P
FX-603P & Manuals 

FX-502P の系統の互換機種の最終バージョンである FX-603Pで、これもきちんと動作します。これは21世紀に入ってもまだ販売されていた超ロングセラーの製品です。私自身、2007年まで使っていたので、そんなに古いと言う感覚がないのですが、残っている保証書には 1992年4月 とあるので、22年も前に購入したことになります。液晶がドットマトリックスになり、2行表示となり、さらにアルファベットの表示ができるようになったのでプログラムの幅が広がりました。当時は2行表示でも凄い便利だと思ったものです。

カシオのプログラム関数電卓第一世代の最終形と言うべき記念のモデルです。

実は、その後カシオのプログラム関数電卓搭載のプログラミング言語は、迷走の時代を迎えます。

fx-4500P
fx-4500P 
迷走の時代の代表選手 fx-4500P です。fx-4500PA は多く売られたのですが、末尾が PA でなくて P のモノはそれほど多く市場に出回らなかったようで、ある意味希少価値があるようです。海外のコレクタが 比較的高値で購入したがっているようです。fx-4500PA はボタン電池を3個使うのですが、fx-4500P はボタン電池2個使いなので、省電力で経済的なのかも知れません。

残っている保証書には、1990年2月27日とあるので、24年選手です。

私の fx-4500P は残念なことに 電池を入れ替えても LOW BATTERY と表示され、液晶が濃く表示できない状態です。計算はできるので、かろうじて動態保存しています。普通に考えれば24年で故障するのは不思議でもなんでも無いのですが、他が凄すぎです。

このモデルの特長として、1つのキーに割り当てられる機能が多すぎで、操作性が悪い点がありました。それだけなら慣れれば済むのですが、プログラミング言語が、中途半端でとても使いにくいのは致命的でした。

右下に [EXE] キーがあるのが、この機種の特長の1つです。当時のカシオは FX-603P 系統の [=] を持つシリーズと、[EXE] を持つシリーズの2つが存在しており、言語仕様が互いに大きく異なっていました。

結果的には、[EXE] キーの系統が、現在のプログラム関数電卓やグラフ関数電卓に繋がっているわけですが、FX-603P でできたことが、どうやっもできないと言うことが多く、せっかく期待して購入したのですが、結局 FX-603P の購入に至ります。

従って、、それほど使っていないのですが、所有品の中でこれだけが電源回りに故障が発生していることから、品質面も試行錯誤していたのかも知れません。私が購入した電卓の中で、唯一のハズレ品でした。


fx-911s / fx-991S / fx-991W / fx-991MS / fx-991ES / fx-993ES
仕事の環境が大きく変わったため、技術計算やプログラムを利用することが激減し、スタンダード関数電卓を愛用していた時期があります。上の写真には写っていない、fx-911s が初めて買った スタンダード関数電卓でした。FX-603P と同様の手帳タイプで、満員電車の押しくらまんじゅうで壊れてしまい、fx-991S を購入。これも同じく手帳タイプで同様に満員電車で壊れました。

次に買ったのが、写真に写っている fx-991W で、ハードケースに変わったおかげで、満員電車で生き残ることができました。fx-991W を最も長く愛用しました。その後、fx-991MS 以降でガッカリしたのは、3桁区切りの記号が表示されなくなったことです。さらに fx-991ES以降では、3桁区切り記号が無いだけでなく、視認性の劣る青液晶になってしまいました。安い青液晶に切り替えたのは、バブル崩壊とデフレ突入による不景気の象徴だと思っています。

幸いなことに2015年2月発売予定の fx-JP900 は、黒液晶に戻り、3桁区切りが復活します。さらに高精細液晶の搭載です。カシオの本気度がうかがえます。


fx-5800P
fx5800P_calc. fx-5800P を店頭で見て、その場で衝動購入したのですが、購入当時はスタンダード関数電卓の高級機と言う感覚で使っていました。プログラムは作らず、使いもしませんでした。

ふと、プログラムを作ってみようと思って触ると、FX-603P とは別世界、スラスラとプログラムが書けて、Casio Basic の使いやすさに驚きました。そして、触っているうちに Casio Basic の能力の高さに惚れ込みました。但し、fx-5800P の取扱説明書は、FX-603P の時代と異なって、プログラミングについては、ほとんどヤッツケ仕事としか思えないお粗末な記述しかありません。カシオは、分かる人だけ使えば良いと本気で思っているのでしょうか? 優れた Casio Basic なのにもったいない話です。

近年の Casio Basic は構造化プログラミング言語なので、実用的で使いやすいプログラムをかけます。その魅力にハマッて色々と調べた結果をまとめておきたい、知らない人に知って欲しいと言う趣旨で e-Gadget  を始め、究極のワンテーマブログが続いています。



fx-9860GII
今年は年末になって、fx-9860GII を入手しました。fx-5800P よりも処理能力は圧倒的に高いのですが、使い勝手の面でみると fx-5800P の方が圧倒的に良いと感じています。従って、今でも日常使いは fx-5800P のままです。チョットした憧れのあった fx-9860GII ですが、どちらか1つを選べ、と今言われると fx-5800P を選ぶと思います。今のところ...

ところで、 fx-5800P 用の Casio Basic のプログラムをいくつか fx-9860GII に移植してみています。

 ⇒ fx-5800P プログラムライブラリ - キーコード取得
 ⇒ fx-9860GII への移植 - ピタゴラス数
 ⇒ fx-9860GII への移植 - 素因数分解

ここで、分かったことは、ほんのチョットしたことだけ気をつければ移植性が極めて高いと言うことです。処理能力の低い fx-5800P でまともに動くように作れば、fx-9860GII では問題なく動作します。搭載されている Casio Basic は、fx-5800P よりも fx-9860GII がバージョンが上のようで、fx-5800P に無いコマンドが多くあるので、fx-5800P でどうしてもできないことが、fx-9860GII で実現します。理屈の上では...です。

実際に、fx-9860GII の特長を活かし、fx-9860GII で是非とも使いたいプログラムが、いつか出来ると思います。fx-5800P になく、fx-9860GII にある面白い点の1つに、C言語で書いたプログラムを走らせられることがあり、ホビー機としては楽しませてくれそうです。Windowsプログラミングが染みこんでしまった体には、以前の MS-DOS で C のプログラムを作っていた頃を思い出させてくれて、懐かしい感じがします。


Basic は時代遅れなのか?

ネットを見ていますと、Basic 言語は教育用の初心者向きで、実用向きではないと言う言説を未だに見聞きしますが、PC用のプログラムでも Visual Basic で書かれたものが立派に業務用として使われています。C言語系(敢えて、C++、C# や Javaなどを含めますが...)が優れていると一言でいえるものでは無いと思うのです。適材適所で 複数の言語を使い分けるのが最良でしょう。プログラミングは宗教ではなく、実用ツールなのですから...

Basicでプログラムを書くのは確かに楽です。電卓プログラミングで言えば、FX-603P 系のアセンプラのような言語に比べると、Casio Basic は圧倒的に実用的です。プログラムの種類や目的によっては、Casio Basic ではできないことがあり、その時は Casio Basic 以外を使いたいと思います。その意味でfx-9860GII により、プログラム電卓活用の幅が広がるのではないかと、楽しみです。


そして、Casio Basic の勧めCasio Basic入門 に繋がります。


長々とここまでお付き合い頂き、ありがとうございます。





応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ




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

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


関連記事

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

fx-9860GII への移植 - ピタゴラス数

2014年12月06日
2014/12/07: fx-9860GII オーバークロックでのテストを追加
2014年12月14日: 配列変数の代わりには行列が良い点を追記

fx-9860GII を入手したので、さっそくピタゴラス数探索プログラムを fx-5800P から移植してみました。
 ⇒ fx-5800P でピタゴラス数

このプログラムについて、fx-5800P のプログラムとの違いは、以下を考慮すれば良いだけの筈です。

・キーコード: Getkey が返す値が 全く異なる
・Locate コマンドの引数: 画面が 21 x 7 と広い

ところで、キーコードを調べるプログラム GET KEYCODE (プログラムライブラリ - キーコード取得 参照) は、そのまま100% 互換で移植できます。fx-9860GII はプログラム名を8文字以内で指定しなければならないので、fx-9860GII のプログラム名を KEYCODE としました。
 ⇒ プログラムライブラリ - キーコード取得

具体的な比較は上記参照。これでキーコードを調べると、[EXE] キーは 31、[(-)] キーは 41 でした。


さて、fx-5800P用のピタゴラス数探索プログラムで、キーコードのみを変更してfx-9860GII で走らせてみると、画面の1行目に

- Disp -

と表示されてしまい、1行目の表示に上書きされていまうことが分かったので、Locate の引数を変更して、表示全体を1行下にずらすようにしました。

表示行を1行下にずらした - ステップモード

9860_Pytha1 


表示を1行下にずらした - 連続モード

9860_Pytha2 


fx-9860GIIピタゴラス数探索プログラム: PYTHA
3→M:1→N:1→D:1→D:1→E     (初期化処理)
Locate 1,3,"A="            
(初期画面表示)
Locate 1,4,"B="
Locate 1,5,"C="

Lbl 0

E=0⇒Locate 14,2,"(-):Stop"
(M2-N2)÷2→A             
(ピタゴラス数の計算)
MN→B
(M2+N2)÷2→C

Locate 1,1,D              (見つかった回数の表示)
Locate 3,2,"          "    (スペース19個)
Locate 3,2,A              
(ピタゴラス数の表示)
Locate 3,3,"          "    (スペース19個)
Locate 3,3,B              (ピタゴラス数の表示)
Locate 3,4,"          "    (スペース19個)
Locate 3,4,C              (ピタゴラス数の表示)

Getkey=41⇒1→E
0→K
While Getkey=31
Isz K:K=20⇒Break
WhileEnd:K=20⇒0→E

Locate 14,2,"EXE:Next"◢    
(操作法表示&プログラム一時停止)

Do                     
(次の M と N を探す)
N-2→N
If N<0:Then
M+2→M:M-2→N
IfEnd
N=1⇒Break
LpWhile Frac(M÷N)=0
Isz D                    
(見つかった回数を1つ増やす)

Goto 0



fx-9860GII は fx-5800P よりもかなり動作が速いようで、[EXE] キー長押しの時間を長く設定しないと長押しにならないことから、fx-5800P で長押し時間のカウンタ 7 だったのを、20 に変更しました。

ピタゴラス数100個を探索する時間を比較してみると

・ fx-5800P:                 40秒
・ fx-9860GII (ノーマル 29MHz):       18秒
・ fx-9860GII (オーバークロック 236MHz):  4秒  [2014/12/07 追記]

と、sentaro様のご報告と同様に、fx-9860GII (ノーマル) は約2倍の速さでした。

[2014/12/07 追記]
ちなみに、sentaro様作アドイン Ftune 2 によるオーバークロックで 約236MHz にすると、上記の通り fx-5800P の10倍の速度となりました。

Ftune 2 は、
こちら
このアドインを起動後、メモリーチェックを行い、F5 キーで上記設定ができました。

なお、オーバークロックに合わせて、長押し検出のカウンタは 150 にしています(そうでないと速すぎてステップモードに切り替えが難しい)。



実際見た目も速くなっています。

ノーマル (29MHz)




オーバークロック (236MHz)



これは、凄い速さですね!



fx-9860GII は、並行輸入品 (¥9,000) なので、添付している紙のマニュアル類に日本語はありません。ところが、添付CDに、日本語のマニュアルがありました。プログラミングについては、fx-5800P と同様に殆ど役に立たない、最低限の内容しか記載がありません。

そこで、開封し、電池を入れて、マニュアルなしでいきなり キーコード取得プログラムを入力してみました。
たった20行のプログラムですが、コマンドをどこから選んで良いのか、最初はサッパリ分からず、結構な時間をかけて入力完了!
これで、大雑把に、どこにどのコマンドがあるのかが分かりました。

このプログラムは、手直し無しで正常動作しました。fx-5800P から fx-9860GII への互換性がかなり高いことが証明されました。

次にピタゴラス数探索プログラムの入力は、かなり楽になりましたが、ここで - Disp - 表示という思わぬ罠がありました。
この表示は、出力命令 ◢ を使うと、現れるようです。

例えば、1行だけのプログラム

Locate 1,1 "1ST LINE"

を実行すると、1行目の左端から、

1ST LINE

と表示されますが、出力命令 ◢ を使って、

Locate 1,1,"1ST LINE"◢

として、実行してみると、1行目の右端に

- Disp -

と表示され、1ST LINE が表示されません。

- Disp - が表示されるとき、その行全体を左端から上書きして表示されているために、1ST LINE が消えているようです。

次に、

""
""
""
""
""
""
Locate 1,1,"1ST LINE"◢


を実行してみると、"" で内部カーソルが6回改行され、7行目に - Disp - が表示されるので、1行目の 1ST LINE は上書きされずに、きちんと表示されます。

このことから、- Disp - は現在の内部カーソルの位置を示していると思われます。

Locate 1,1,"1ST LINE"◢

が正常に表示されない問題を避ける方法がないものか、もう少し調べて見ようと思います。


他にも、色々と触っていて気付いたのですが、fx-9860GII には配列変数がありません。その代わりに List コマンドを使うしかないのかなぁ、と思いますが、その処理速度がどの程度か、いずれ調べてみようと思います。

[2014年12月13日 追記]
fx-9860GII (ノーマルクロック: 約29MHz) でリストと行列のアクセス速度を測定したところ、行列の方が速いことが分かりました。速度と汎用性を考えると、fx-5800P の配列変数の代わりに fx-9860GII で行列を使うのが正解です。

処理内容処理時間 (ミリ秒)
リスト読み出し13.2
リスト書き込み17.6
行列読み出し10.7
行列書き込み12.0
※ 測定はココ の方法に準じて実施。但しループ回数は2000回とした。


fx-9860GII は標準で 29MHz程度。クロックが8倍速くなっているのに、表示まで含めた速度は4.5倍程度にとどまっている、という上記の結果から、表示(描画)速度がかなり遅くて、これが全体の速度を決めてしまう(律速)ことになっているようです。

fx-5800P が14MHzも無いとするならば、fx-5800P の描画速度がfx-9860GII に比べて速いと言えます。




fx-9860GII 用ピタゴラス数探索プログラム: PYTHA

※ fx-9860GII へ転送して使える プログラムファイル pytha.g1m のダウンロード

fx-9860GII PYTHA_src 
 ※ 13行目、15行目、17行目の Locateコマンドの空白はスペース19個




応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ



keywords: プログラム関数電卓、fx-5800P、fx-9860GII、キー長押し、CasioBasic、 ピタゴラス数

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

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

fx-5800P:変数アクセス、比較・論理演算、条件分岐の速度比較

追記: 2014年12月13日

fx-5800PCasio Basic でプログラムを書いていると、コマンドや命令の使い方で、処理速度が大きく異なることに気づきます。

条件分岐(If 文や ⇒ 命令)、ループ (Do、While For)については以前調べています。
 ⇒ fx-5800P コマンドの処理速度【再編集】


fx-5800P の Casio Basic では配列変数を使えて便利ですが、これを使うと処理速度が大きく低下することが経験的に分かっています。

そこで、配列変数と同様な使い方のできるリストと行列を含めて、これらの処理速度を調べてみます。比較のために通常変数も併せて調べます。

fx-5800P 搭載の Casio Basic には、プログラムで変数として使えるものに、以下があります。
 ・通常変数: AZ の 26 個
 ・配列変数: Z[ ]
 ・リスト: List X[ ]List Y[ ]Freq[ ] (要素数は最大199)
 ・行列: Mat A[ ] (行列名に AZ が使える、要素数は、行・列それぞれ最大10)

論理演算(And、Or、Not)も体感的に重い処理だと分かっているので、比較演算(=、≠、<、>、≦、≧)と合わせて速度を調べてみます。



測定方法

測定し易いようにループで1000回実行させ、スマートフォンのストップウォッチアプリで、時間を計ります。
測定用のプログラム ST (Speed Test) は、以下のようにします。

・プログラム名ST xxxx (xxxx は計測対象が分かるような表現にする)

・プログラム
[必要な初期設定]
1000→A
"ST:xxxx"◢
Lbl 0
[測定対象]
Dsz A
Goto 0

必要な初期設定の後、出力命令  でプログラムは一旦停止。[EXE] キーを押すと同時にストップウォッチをスタート。
ループが1000回まわって、プログラムが終了すると画面表示が変わるので、そのタイミングでストップウォッチを止める。

但し、fx-5800P を使っていて、処理速度の個体差や、バッテリーLOW時の速度低下(電池を入れ替えると速度が上がる)などでの速度差を体感しています。さらに、fx-5800P ではクロック発生用に比較的精度のある発振子使っていない可能性があり、クロックが環境条件や電池の電圧の影響を受ける可能性がある、との情報を頂いております。⇒ sentaro様のコメント

従って、ここでの測定値は絶対値として評価することに意味はありません。基準ループとの相対的な処理時間差に着目し、その目安として測定値(ミリ秒)を用いることにします。

測定は5回行って、最大値と最小値を外し、残り3つの値の平均を計算して測定結果とします。なお私の反射神経では、小数点一桁目までは比較的再現性が高いことから、小数点1桁目までを有効数字として使い、小数2桁以下は切り捨てます。



基準ループ

1000→A
"ST: L-G"◢
Lbl 0
Dsz A
Goto 0


基準ループ測定結果: 5.9

以前、fx-5800P コマンドの処理速度【再編集】 では、上記のプログラムの最後に "DONE"◢ があります。そこでこの表示を加えたものを今回測定すると、6.1 秒 でした。以前の記事を書いた時の測定時結果が 6 秒で、前回と今回の速度差は、"DONE"◢ 表示によるものと考えらます。今回の測定での表示による速度差が 0.2 秒 なので、fx-5800P のクロック変動および測定誤差を考えると、今回の基準ループの測定結果は妥当と考えて良さそうです。

前回測定 (秒)今回測定 (秒)
"DONE"◢ 有り66.1
"DONE"◢ 無し---5.9

さて、測定対象を含んだプログラムの測定結果から基準ループ測定結果を引き算して、測定対象の処理時間を求めます。
[測定結果 (秒)] - 5.9 秒 = [測定対象の処理時間 (秒)]

これは、1000回繰り返した結果なので、1000 で割って一回あたりの処理時間 (ミリ秒) を計算します。



通常変数

先ずは、通常変数のアクセス速度を調べます。

1000→A:0→B
"ST:B"◢
Lbl 0
A→B
Dsz A
Goto 0


測定結果: 11.3 秒

[測定結果] - [基準ループ測定値] = [目的の処理時間] なので、
通常変数アクセス時間: 11.3 - 5.9 = 5.4 秒
これは、1000回実行した時の時間なので、

通常変数アクセス時間: 5.4 ミリ秒



配列変数

配列変数からの読み出しと書き込みの両方を調べました。

配列変数読み出し
0→DimZ
10→DimZ
1000→A:0→B
"ST:Z[ ] READ"◢
Lbl 0
Z[2]→B
Dsz A
Goto 0


測定結果: 28.6 

配列変数読出し時間: 28.7 ミリ秒


配列変数書き込み
0→DimZ
10→DimZ
1000→A
"ST:Z[ ] WRITE"◢
Lbl 0
A→Z[2]
Dsz A
Goto 0


測定時間: 27.9 ミリ秒

配列変数書込み時間: 22.0 ミリ秒

配列変数は、読み出しよりも書き込みが若干速いようです。これは予想外です。
配列変数へのアクセスは、通常変数の4倍弱の時間がかかることが分かりました。
速度を要求するところでは、配列変数へのアクセスを極力減らすべきです。



リスト

Casio Basic には、統計計算を行うために List が用意されています。
List は、1項目あたり、List X[ ]List Y[ ]List Freq[ ] と3つの配列が対応し、それぞれの配列の要素数は最大199です。
言い換えれば、1つの要素インデックス K に対して、List X[K]List Y[K]Freq[K] の3つの配列が使えるので、便利そうです。

XYFreq いずれも処理速度は同じと思われるので、測定には List X[ ] を使い、読み出しと書込の両方を調べました。

List 読み出し
ClrStat
{0,0,0,0,0,0,0,0,0,0}→List X
1000→A:0→B
"ST:LIST READ"◢
Lbl 0
List X[2]→B
Dsz A
Goto 0


測定結果: 31.0 秒

リスト読み出し時間: 25.1 ミリ秒


List 書き込み
ClrStat
{0,0,0,0,0,0,0,0,0,0}→List X
1000→A
"ST:LIST WRITE"◢
Lbl 0
A→List X[2]
Dsz A
Goto 0


測定結果: 31.2 秒

List 書き込み時間: 25.3 ミリ秒


List は、読み出しより書き込みに時間がかかるようです。
List へのアクセス時間は、配列変数よりも少し時間を要することが分かりました。
List の利便性は魅力がありますが、List を使うくらいなら、配列変数を使った方が少しは処理が速いことが分かります。


いずれにせよ、高速処理が必要なところでは List へのアクセスを最小限に抑えるのが良いことが分かります。



行列

fx-5800P の Casio Basic では正式に行列をサポートしていませんが、実際は使えます。
行要素、列要素それぞれ最大10です。言い換えれば、最大で、要素10の10次元配列が使えるわけで、処理内容に応じては大変便利なものです。行列についても、読み出しと書き込みの両方で測定しました。

行列読み込み
ClrMat
[[0,0,0,0,0,0,0,0,0,0]]→Mat A
1000→A:0→B
"ST:MAT READ"◢
Lbl 0
Mat A[1,2]→B
Dsz A
Goto 0


測定結果: 32.8 秒

行列読み出し時間: 26.9 ミリ秒


行列書き込み
ClrMat
[[0,0,0,0,0,0,0,0,0,0]]→Mat A
1000→A
"ST:MAT WRITE"◢
Lbl 0
A→Mat A[1,2]
Dsz A
Goto 0


測定結果: 34.3 秒

行列書き込み時間: 28.4 ミリ秒


行列は、読み出しよりも書き込みに若干時間がかかるようです。
行列のアクセス時間は、List よりもさらに時間がかかることが分かります。
速度を要求する場合は、どうしても必要性がある場合を除いて、使わないのが良いことが分かります。


以上、配列として使える、配列変数、リスト、行列 について調べた結果は、通常変数に比べて4倍程度のアクセス時間がかかることが分かり、速度を要求する場合には、極力アクセス数を減らすようなプログラムの書き方が必要なことが、明確になりました。



続いて、論理演算と比較演算の処理速度を調べます。

論理演算

fx-5800P の論理演算子には、And、Or、Not があります。いずれの処理速度も同等だと考え、測定には And を使います。

1000→A:0→B
"ST:LOGIC"◢
Lbl 0
A And B
Dsz A
Goto 0


測定結果: 15.9 秒

論理演算処理時間: 10.0 ミリ秒

論理演算1回だけの処理時間としては、短いとも長いとも言えないでしょう。しかし論理演算を多用すると、プログラムの実行速度が大きく損なわれることが分かりました。速度を要求する場合は、論理演算を極力控えた方がよさそうです。



比較演算

fx-5800P の Casio Basic の比較演算子には、=<> があります。
いずれの処理速度も同等だと考え、測定には を使い、[変数]≠[変数]、と [変数]≠[数値] の測定を行います。

変数との比較演算
1000→A:0→B
"ST:COMP B"
Lbl 0
A≠B
Dsz A
Goto 0


測定結果: 15.6 秒

変数との比較演算時間: 9.7 ミリ秒


数値との比較演算
1000→A
"ST:COMP 2"◢
Lbl 0
A≠2
Dsz A
Goto 0


測定結果: 17.4 秒

数値との比較演算時間: 11.5 ミリ秒


変数との比較演算よりも数値との比較演算に時間がかかるのは、興味深い結果です。
比較演算を行う時は、即値(数値)を使うのではなく、変数を利用するほうが処理が速くなることが分かります。

論理演算で即値を使うケースとしては、If A=0 といった処理をよく使います。
この場合は、0→C としておき、If A=C とする方が処理が速いわけで、条件分岐を多く使う場合は特に効果があります。
一方、If A≠0 とする場合は、迷わず If A とすべきでしょう。



そこで、一連の測定を行ったついでに、同じ環境条件、電池消耗条件で、If 文の処理速度も測定してみて、今回の一連の測定結果の中で、相対的にどの位置にくるのかを調べてみます。

If A≠B

1000→A:0→B
"ST:ID A B"◢
Lbl 0
If A≠B:Then
Dsz A
Goto 0

IfEnd


測定結果: 17.9 秒

If A≠B の処理時間: 12.0

この処理時間には、比較演算 A≠B が含まれているので、変数との比較演算の 9.7 ミリ秒がこの処理の多くを占めていることが分かります。


If A≠0

1000→A
"ST:IF A 0"◢
Lbl 0
If A≠0:Then
Dsz A
Goto 0

IfEnd


測定結果: 19.6 秒

If A≠0 の処理時間: 13.7 ミリ秒

B=0 の B を使ったIf 文よりも 即値 0 を使った If 文の方が 1.7ミリ秒時間がかかりますが、比較演算の変数と即値での違いの 1.8 ミリ秒に近いことが分かります。If 文では、変数を使った速い比較演算を行う方が良いことが明かです。 これは、面白い結果です。


If A

ここまでみてくると、変数が真が偽かの判定のみの場合が気になります。

1000→A
"ST:IF A"◢
Lbl 0
If A:Then
Dsz A
Goto 0

IfEnd


測定結果: 12.1 秒

If A の処理時間: 6.2 ミリ秒


比較演算を使わないと、処理速度が大幅に向上することが、今回も確認されました。


A⇒

If A よりも A⇒ の処理が速いことは既に分かっています。今回の一連の測定で、相対的にどの位置に来るのか調べて見ました。

1000→A
"ST:JUMP"◢
Lbl 0
Dsz A

A⇒
Goto 0


測定結果: 10.0 秒

A⇒ の処理時間: 4.1 ミリ秒

とても速い結果となりました。比較演算がなく、さらに IfEndへのラベル検索動作も無いことが、この結果を説明するのだと思います。


A≠B⇒ [2014/12/13 追記]

では比較演算式と条件分岐 ⇒ の組み合わせは、どうなるでしょうか?

1000→A:0→B
"ST:COMP JUMP"◢
Lbl 0
Dsz A

A≠B⇒Goto 0


測定結果: 15.9 秒

A≠B⇒ の処理時間: 10ミリ秒

比較演算が含まれますが、それでも If A≠B よりも 2 ミリ秒速いことが分かりました。条件分岐した結果の処理がコマンド/命令1つの場合は、A≠B⇒ を使う方が処理が速いことが分かります。


If A Else

1000→A:0→B
"ST:IF A ELSE"◢
Lbl 0
If A:Then

Dsz A
Goto 0

Else
IfEnd


測定結果: 13.1 秒

If A Else の処理時間: 7.2 ミリ秒

条件ジャンプ命令 を2つ使うよりも、If A Else を使った方が、間違いなく速いことが分かります。



テキスト表示 [2014/12/12 追記]

ダイナミックに数値の変化を表示するような場合は、表示速度のプログラム全体への影響が大きくなります。そこで Locate コマンドによる表示の速さを測定してみます。

1000→A
"ST:Locate"◢
Lbl 0
Locate 1,2,A
Dsz A
Goto 0


測定結果: 26.3 秒

Locate の処理時間: 20.4 ミリ秒

今回評価した中で、Locate コマンドによるテキスト表示は相対的に重い処理であることが分かります。



今回の結果を表にまとめます。

これまで感覚的に思っていたことの定量的な裏付けがとれました。
今後はこれを参考にして、速い処理が必要な時の指針にしようと思います。

表 fx-5800P Casio Basic 処理時間の比較
処理内容処理時間 (ミリ秒)
A⇒4.1
通常変数アクセス5.4
If A6.2
If A Else7.2
比較演算(変数)9.7
A≠B⇒10.0
論理演算10.0
比較演算(数値)11.5
If A≠B (変数)12.0
if A≠0 (数値)13.7
テキスト表示 (Locate)20.4
配列変数書き込み22.0
配列変数読み出し22.7
リスト読み出し25.1
リスト書き込み25.3
行列読み出し26.9
行列書き込み28.4
※ 処理時間は、基準ループからの相対差で得られたもので、絶対値に厳密性はありません。


[2014/12/12 追記]
今回作った測定用ルーチンを、全て1つのプログラムファイルにまとめて実行させるとどうなるか?
先ず、Lbl / Goto は、各測定ルーチンごとに、異なる番号を指定する必要があります。

Lbl 0 / Goto 0
Lbl 1 / Goto 1
Lbl 2 / Goto 2
   ・
   ・
   ・

試しにやってみました。
すると、予想通りに基準ループの測定値(本来 5.9 秒) が3倍に増えました。

Lbl / Goto は fx-5800P では最も速いループ構造ではありますが、Goto によりラベルを探すのにそれ相当の時間がかかっているので、探すラベルの数が増えれば目に見えて余計に時間がかかります。

Lbl / Goto を多用すると、ラベル検索のために大幅な処理速度の低下に繋がることが確認されました。

私自身、ついつい忘れそうなので、追記しておきます。




応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ




keywords: fx-5800P、プログラミングCasioBasicプログラム関数電卓

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


関連記事

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

fx-9860GII USB POWER GRAPHIC 2

2014年12月09日
2015年1月13日 追記


やっぱり fx-5800P が好き

5800と9860、外観 

fx-9860GII と fx-5800P を並べてみる。このくらい違う。厚みが倍近いので、fx-5800P の一回り大きいのが fx-9860GII。やはり、持ち歩くなら fx-5800P のほうが良いと思います。小型・軽量・十分な機能を備えているからです。


関数電卓として

fx-5800P の方が、ひと押しで使える関数キーが多いので、一見 fx-5800P が良いように思えますが、これは慣れの問題だと思います。

ところで、

235÷658

と入力して [EXE] キーを押すと、

fx-9860GII は、0.3571428571 と表示し、[F-D] キーを押すと、5/14 と分数表示になります。
fx-5800P は、5/14 と先ず表示し、[S-D] キーを押すと 0.3571428571 と表示が変わります。

電卓で計算する時、欲しいのは小数であって、分数でないことが殆どです。fx-9860GII の方が優れていると言えます。


5800と9860、複素数 

上の写真の両機の画面を見てください。πi  を計算させようとしています。

この は複素指数関数で、複素数計算を非常に楽にしてくれる便利モノです。

 e(a+bi) = (cos b + i sin b)

例えば、a = 0、b = π の場合は、π = -1 と言う「オイラーの恒等式」が得られます。映画「博士の愛した数式」で有名になったものですね。

私が知っている範囲の国産のスタンダード関数電卓やプログラム関数電卓で、これを正しく計算できるものはこれまで見たことがありませんでした。グラフ関数電卓はワンランク上なのですね(グラフ関数電卓を初めて触った感想)。

左の fx-5800P は、a + bi 形式や極形式の複素数計算はできますが、このような複素指数関数を使って、このまま [EXE] キーを押すとエラーになって計算できません。

ところが、fx-9860GII ではこれを計算でき、正しく -1 と結果がでました。これは、チョット感動モノです。
(5/3)π を計算させると、1/2 - (√3/2)i と正しく答えが得られます。


プログラム電卓として

さて、両機ともプログラミング言語として Casio Basic が使えます。fx-5800P の Casio Basic で作ったプログラムの幾つかを fx-9860GII に移植していますが、比較的移植性は高いと言えます。

 ⇒ プログラムライブラリ - キーコード取得
 ⇒ fx-9860GII への移植 - ピタゴラス数
 ⇒ fx-9860GII への移植 - 素因数素分解
 ⇒ fx-9860GII への移植 - 厄介な旧来の命令

[2015/01/13 追記]
Casio Basic は、古くからのカシオのプログラム電卓との互換性を保つための旧来の命令とBasicコマンドから成り立っています。Basic命令については fx-5800P との互換性は非常に高いと言えますが、旧来の命令については細かいところで fx-5800P との互換性が崩れています。但し対処方法はあります(上記の移植に関する記事参照)。詳細に見てゆくと旧来の命令とBasicコマンドが最もバランス良く実装されているのが fx-5800P と言えます。

fx-9860GII でプログラムを走らせる最大の利点が、その処理速度でしょう。加えて、文字列が扱えること、I/O機能、プログラムのPCへの保存機能なども fx-9860GII の利点です。

fx-9860GII は C言語開発SDK を使ってPCで作ったアドイン・プログラムを転送して使えます。Casio Basic では出来ないことが、C言語で出来るし、同じプログラムなら C で書いた方が動作が格段に速くなります。これも利点の1つでしょう。

ちなみに、fx-9860GII は、CPUのクロックアップが可能で、かなりの高速化が可能になります。
sentaro様が開発された Ftune 2 と言うアドインを、私は使っていて、高速動作をしたい時は、ノーマルの 29MHz程度から一気に 236 MHz のオーバークロック動作ができます。その差は歴然です(上記の2つの移植記事を参照)。

 ⇒ Ftune 2: fx-9860GII のオーバークロック・アドイン、他の機種への対応バージョンもあります。


プログラムの動作速度だけが評価基準ではありません。作ったプログラムの使いやすさを考えますと、チョット話しが違ってきます。

私自身が 必要に迫られて、そしてあったら便利だと思って、複数のプログラムを作って、ほぼ毎日使っています。 fx-5800P では [FILE] キーを押せば、プログラムリストが出てきます。最大5つのプログラムをリストのトップに表示させることもできます。日常使いのプログラムは、このトップ5に入っています。

電源ON [FILE] キー [▼] キー数回

これで、プログラムを呼び出して実行できます。
トップ5にないプログラムを探す際には、プログラムリストが表示されている時は、自動的にアルファベット入力モードになっているので、プログラム名の頭のアルファベットのキーを押すだけで、近い名前のプログラムが呼び出されます。非常によく考えられています。

残念ながら、fx-9860GII では、このようなことが出来ません。

このプログラム呼び出しの迅速性、関数電卓としての操作性、そして携帯性の良さから、私は fx-5800P を日常使いから外すことはないと思います。fx-9860GII が日常使いになるには、何か新しい事情が必要でしょう。

まだ、グラフ機能や作表機能を試していません。プログラムからグラフ機能を使うことも出来ますので、このあたりに fx-9860GII の下克上の可能性はありそうです。


最近の価格

Casio fx-9860GII は、グラフ関数電卓と言われるジャンルの製品で、電卓製品のなかでは最も高機能なものです。その分販売価格も高くなっています。日本では、アメリカの2倍近い価格設定なので、日本国内で入手しようという気は全くありません。

先週末 Amazon で並行輸入品が ¥9,000 でありました。本日見ると ¥8,980 と、ついに8,000円台に突入しました。
fx-5800P が Amazon で¥6,261 なので、fx-9860GII は買い時になったと思われます。

[2014/12/20 追記] 
昨日 Amazon を見てみると、fx-9860GII 並行輸入品が ¥8,500 とさらに値下げされていました。年末セールなのかも知れませんが、どこまで下がるのか楽しみです。ちなみに fx-5800P は¥6,235 になっていて、これも値下げが進んでいます。
恐らく、今の年末セールから3~4月の新学期シーズンまでが安値が期待できるように思います。


製品保証?

上記の価格は並行輸入品のものですから、製品保証の問題がグレーゾーン。保証書の紙は製品に添付されていますが、販売店のスタンプが押されていません。購入店のある国内でのみ保証有効、との注意書きの紙も添付されていました。私はアマゾンで購入しましたが、それは日本国かどうかがグレーです。国内で対応してくれるかは分かりません。






応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ




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

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


関連記事

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

fx-9860GII への移植 - 素因数分解

2014/12/13: 修正
2015/02/28: 追記

これまで、fx-5800P の Casio Basic で素因数分解のプログラムを紹介してきたが、これを fx-9860GII へ移植してみました。

今回のプログラム移植にあたっては、fx-5800P にある 配列変数 Z[ ] が fx-9860GII には無いので、これをどうするか、が主なテーマです。今回は、配列変数の代わりに行列を用いることにします。

なお、出力命令 ◢ を使った時の動作が、fx-5800P と fx-9860GII では異なることは、ピタゴラス数探索プログラムの fx-9860GII への移植 で経験しています。⇒ こちらの記事

これは、本来表示される筈の行が上書きされて - Disp - と表示されてしまう問題です。今のところ、決定的な解決策がまだ見つかっていないので、表示全体を1行下に下げると言う方法で回避することにします。



配列変数を行列に置き換える

配列変数 Z[N] は、1行N列の行列と同じなので、以下のようにします。

1. 領域確保 (要素20個を確保して、各要素を 0 で初期化する)
  ・配列変数の確保: 20→DimZ
   の代わりに
  ・1行20列の行列確保: {1,20}→Dim Mat Z
   [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]→Mat Z これでも間違いないが、効率が悪い。
   fx-9860GII の Casio Basic では 最大999行999列の行列まで使えるので、Dim コマンドを用いるべき。

   [2014/12/08 sentaro様のご指摘により記述を修正]

2. 使い方
  ・ 配列変数: Z[K]
   の代わりに
  ・行列 Z : Mat Z[1,K]

3. 領域解放
  ・配列変数の解放: 0→DimZ
   の代わりに
  ・行列 Z の解放: ClrMat Z

要するに、プログラムの記述を、上のように置き換えれば動作するはずです。



- Disp - 表示による問題の回避

Locate コマンドで指定する座標を 下に1つ増やす (Y座標を1つ増やす) ことで対応します。
今回は、多くの Locate コマンドの座標指定に変数や式を用いているので、チョット注意が必要です。但し、今回のプログラムで使っているLocate コマンドのY座標は、変数 L やLを使った式で指定しているので、L の値を1つ増やすように変更すれば良さそうです。具体的には、一番下に示すプログラムを見てください。



全画面消去コマンドの変更

fx-5800P の全画面消去は Cls コマンドを使用します。テキスト表示の全消去機能です。
一方、fx-9860GII は、テキスト表示とグラフィック表示の両方の機能があり、テキスト表示の全消去は ClrText コマンドを使います。
ちなみに、グラフィック表示の全消去コマンドは ClrGraph と Cls の両方が使えます。


今回は、配列の扱い、出力命令の動作と画面行数に合わせたLocateコマンド引数の修正のみで、fx-9860GII に移植したプログラムは問題なく動作しました。要所を分かっていれば、Casio Basic は移植性が高いと言えます。



プログラム実行画面

fx-5800P と fx-9860GII の両方で、ほぼ同じ Casio Basic プログラムを走らせた時の、画面表示の比較です。


※プログラムを起動した時の画面:

PD_5800P_1 PD_9860GII_1 


※数を入力する:

PD_5800P_2 PD_9860GII_2  


※素因数分解を最後まで計算したあとで、結果を表示:

PD_5800P_3 PD_9860GII_3  

1行表示されたら [EXE] キーを押して次の行を表示させます。
これを繰り返して、上のように が表示されたらそれが最後の素因数です。
ここで、 [EXE] キーを押せば最初の入力画面に戻ります。

fx-5800P では4行を超えると再び1行目から上書きします。
fx-9860GII では7行を超えると再び行目から上書きします。



計算速度の比較

fx-9860GII は、ノーマル (約29MHz) と オーバークロック (約236MHz) で測定しました。

入力した自然数結果fx-5800Pfx-9860GII (29MHz)fx-9860GII (236MHz)
123453 x 5 x 8232.2秒0.5秒 (4.4倍)計測不能 (一瞬)
12345626 x 3 x 6432.6秒0.6秒 (4.3倍)計測不能 (一瞬)
1234567127 x 97216.5秒1.5秒 (4.3倍)0.3秒
123456782 x 32 x 47 x 145936.6秒1.5秒 (4.3倍)0.4秒
12345678932 x 3607 x 38032分43秒33秒 (4.9倍)7.2秒
98765432132 x 172 x 37972128秒6秒 (4.7倍)1.3秒
9876543223 x 37 x 33366727秒5.5秒 (4.9倍)1.3秒
98765433 x 227 x 1450311秒2.4秒 (4.6倍)0.6秒
9876542 x 3 x 97 x 16975秒1.3秒 (3.8倍)0.4秒
987655 x 197537秒1.6秒 4.3倍)0.3秒
987622 x 3 x 8233秒0.7秒 (4.3倍)計測不能 (一瞬)

今回の速度比較には、表示速度は含まれず、プログラムの実行速度の差が反映されていると考えられます。

※ オーバークロックは、sentaro様作のアドイン Ftune 2 を使用しています。Ftune 2 については、こちら を参照のこと。




プログラムの比較

左が fx-5800P 用プログラム、その右に fx-9860GII 用に変更したプログラムを並べ、変更箇所を赤文字で示しています。

[2015/02/28 追記]
※ fx-9860GII へ転送して使えるプログラムファイル prime.g1m のダウンロード

素因数分解_改造版ソース PD2_9860GII_src 



応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ




keywords: fx-5800P、fx-9860GII素因数分解、プログラム関数電卓

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


関連記事

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

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

やす (Krtyski)

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


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

プログラム電卓を実際に使って気づいたこと、自作プログラム、電卓での Casio Basic, C.Basic そして Casio Python プログラミングについて書いています。

なお管理人はカシオ計算機の関係者ではありません。いつでもどこでもプログラミングができるプログラム電卓が好きな1ユーザーです。


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

ブロとも申請フォーム

この人とブロともになる

QRコード
QR