Casio Basic入門52

Casio Basic入門
<目次>

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

 修正 2016/07/17

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

Chapter 9 - 初級

前回: Casio Basic入門51 を見る


◆ Chapter 9 の目標: 簡単な換算プログラム - 入力ボックスの活用


Chapter 9-2 
fx-5800P で3桁区切り表示をする

前回作った複利計算プログラムですが、金額の桁数が多い時、どうも見づらいので、金額を3桁区切りで表示するようにしてみます。

例えば、1234567812,345,678 とコンマで3桁区切りすると見やすくなりますね。

金額を格納している変数は、B、T、M の3つです。そこで、これらを表示するコードをサブルーチン 3DIGIT に置き換えることにして、今回はこのサブルーチンを作ってみます。


先ずは、前回作ったプログラムです。

ファイル名: COMPINT
Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


0→B:0→R:0→N:0→T:0→M

Do

0→K:Do
Getkey→K
LpWhile K=0
K=73⇒Break

If K=35
Then
5→X:1→Y:9→D:1→E
Prog "INP":Z→B
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース9個)
Locate 7,3,T
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース9個)
Locate 7,4,M
IfEnd

LpWhile 1
Cls
Locate 7,2,"BYE!"



青文字で示した Prog "INP" は、このサブルーチンを実行するだけで値が表示されるので、敢えて Locate X,Y,B を書く必要がありません。しかし、

Prog "INP":Z→B 

の下に、Locate X,Y,B  を追加しても何も変わらず問題ないので、取りあえずこれを追加しておきます。

上のプログラムでは、赤文字で示した Locate コマンドが2カ所あり、今もう1つ追加しました。

そこで、一旦下のように変更しておきます。ファイル名を COMPINT2 に変更しておきます。


ファイル名: COMPINT2
Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


0→B:0→R:0→N:0→T:0→M

Do

0→K:Do
Getkey→K
LpWhile K=0
K=73⇒Break

If K=35
Then
5→X:1→Y:9→D:1→E
Prog "INP":Z→B
Locate X,Y,B
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース9個)
Locate 7,3,T
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース9個)
Locate 7,4,M
IfEnd

LpWhile
 1
Cls
Locate 7,2,"BYE!"



これでも問題なくプログラムは動作します。。


その上で、これら赤文字の3つの Locate コマンドを、Prog "3DIGIT" に置き換えることにして、先に サブルーチン 3DIGIT を作ることにしましょう。



サブルーチン 3DIGIT 使い方の方針を決める

このサブルーチンを目的通りに動かすには、3桁区切りで表示する数値、表示位置 X, Y の3つの要素が必要です。
そこで、表示する数値を 変数 X、表示位置を X と Y と決めて、

例えば、金額 B (元本) を3桁区切りで表示させるため、

Locate X,Y,B

の代わりに、

B→Z:5→X:1→Y
Prog "3DIGIT"


と記述することにします。(この場合は、X と Y は既に指定されているので、特に必要ないが、念のため...)

Casio Basic の変数は、全てのプログラムファイルで共有されるので、サブルーチンの直前で変数を設定すれば、その変数をサブルーチンで使えるわけですね。




3DIGIT のロジックを考える

数値 Z を使って、どのようにしてコンマ記号で3桁区切りを行うのか、色々な方法があると思います。
ここでは、分かり安い方法の1つとして、数値の各桁を、左から順に1桁づつ表示を行い、途中で必要なところにコンマ , を表示する作戦にしてみます。

変数 Z に 12345678 が格納されているとして、X 桁目、Y列目から表示するとします。
左から、1桁づつ数字を拾って、変数 C に一旦格納し、Locate X,Y,C で表示.... X を1つ増やしながら、これを繰り返す作戦にします。途中でコンマが必要なら、Locate X,Y,"," を実行すれば良いですね。

コンマの表示は後回しにして、先ずは数字だけを表示するルーチンを作ることにします。ここでは、以下のような方法を採用することにします。


概略の方針を決める

1) 1234567810 で何回か割り算して、1.2345678 にしてから、小数部を取り除く、つまり Int(1.2345678) を実行すれば、1 になりますね。
2) 取り出した1桁の数字を Locate コマンドで表示します。
3) 次に、12345678 の一番左の 1 を取って、2345678 にして、これを手続き 5) と 手続き 6) で使います。
4) この数字の次に3桁区切り文字(コンマ)が必要な時には、続いて Locate コマンドでコンマを表示します。

5) 234567810 で何回か割り算して、2.345678 にしてから、Int(2.345678) を実行すれば、2 になります。
6) 取り出した1桁の数字を Locate コマンドて表示します。
7) 続いて、2345678 の一番左の 2 を取って、345678 にして、後で一番左の 3 を取り出すのに使います。
8) この数字の次に3 桁区切り文字(コンマ)が必要な時だけ、続いて Locate コマンドでコンマを表示します。

1回目の 1) ~ 4) の手続きと 2回目の 5) ~ 8) の手続きは同じなので、これを 12345678 の桁数と同じ回数だけ繰り返せば、3桁区切りした数値が表示できますね。

これで方針が決まったので、少し具体的な方法へ展開してゆきます。


方針をプログラムコードに変えてゆく - 3桁区切りなし

繰り返し処理で、同じ手続きを所定の回数繰り返す方針ですが、回数を変数 I で管理することにします。1回目は I=1、2回目は I=2 です。

12345678 は8桁なので、桁数の変数を D として、D8 を格納しておきます。Dは計算できます(後で紹介)。すると、繰り返し処理は、D回行えば良いですね。

例に挙げている 12345678 は変数 Z に格納されてます。サブルチン 3DIGIT を実行する前に、3桁区切りで表示する数値は変数 Z に、表示する位置(桁と行)を XY に指定することにしていますね。

すると、手続き 1) ~ 4) では、I=1 です。

手続き 1)
12345678 (=Z)は8桁(D=()なので、10 で7回割り算すれば 1.2345678 になりますね。つまり、12345678 の桁数が D なので、10(D-1) 回割り算すれば良いことになります。10(D-I)回割り算するのは、10(D-I) で割れば良いですね。
そして、Int( ) コマンドで小数部を取り除いて得られる1桁の数を変数 C に格納することにします。これをプログラムで表現すると、

Int(Z÷10^(D-I))→C

となります。ここで、I=1 になっています。


手続き 2)
手続き 1) で得られた C (=1)Locate コマンドで表示します。ここで表示する位置は X桁、Y行なので、

Locate X,Y,C

となりますが、繰り返し処理を考えると、2回目や3回目でも通用する書き方が必要です。そこで、I を用いて、以下のようになります。

Locate X+I-1,Y,C


手続き 3)
12345678 (=Z) の一番左の数字 1 が算出され、変数 C (=1) に格納されています。
この手続きでは、一番左の数字を取って、2345678 にするために、12345678 - C x 10000000 (8桁)を計算すれば良いです。10000000 (8桁)は、108 ですね。今は、D-I = 8 なので、108 = 10(D-I) です。
ここで得られる 2345678 は、変数 Z に再度格納して、手続き 5) 以降で使います。

以上をプログラムで表現すると、

Z-C10^(D-I)→Z

となります。



手続き 4)
必要ならコンマを表示する...これは後で考えます。


これまでのところをまとめ、手続き 1) から 4) を、繰り返すには、


For 1→I To D
Int(Z÷10^(D-I))→C
Locate X+I-1,Y,C
Z-C10^(D-I)→Z
[必要ならコンマを表示]
Next

で良いはずです。

さて、変数 A に格納されている数値の桁数、、例えば 12345678 の桁数を知る方法は、当ブログの逆引きCasio Basic で紹介しています。
具体的には、整数の桁数を求めたい - 逆引きCasio Basic にあります。

A に格納されている整数の桁数 D を得るには、以下のプログラムになります。

Int(log(A))+1→D

この1行を、上の For 文の前に書く必要があります。


Int(log(Z))+1→D

For 1→I To D
Int(Z÷10^(D-I))→C
Locate X+I-1,Y,C
Z-C10^(D-I)→Z
[必要ならコンマを表示]
Next

では、このロジックが正しいかどうかを 手続き 5) から 8) で検証してみましょう。

手続き 5)
繰り返し2回目なので、I=2 になっています。そして、Z=2345678です。
Z は7桁なので、10 で6回割り算すれば、つまり 10(D-I) で割れば、2.345678 になり、これから小数を取り除くと 2 になります。

Int(Z÷10^(D-I))→C

が実行されると、C=2 になって、正しいことが分かります。


手続き 6)
手続き 5) で得られた C を表示するには、

Locate X+I-1,Y,C

で問題ないでしょうか
今は、繰り返し2回目なので、I=2 なので、手続き 2) で表示した隣に桁に C が表示されますね。
これで正しいことが分かります。


手続き 7)
2345678 から頭の 2 を取って 345678 を求めて、改めて変数 Z に代入します。

Z-C10^(D-I)→Z

で正しいでしょうか

今、Z=2345678C=2D=8I=2 なので、
Z-C10^(D-I) を計算すると、

2345678 - 2 x 10(8-2)
= 2345678 - 2000000 = 345678


となり、正しいことが分かります。


手続き 8)
必要なら、コンマを表示する...これは後で考えます。


これで問題なさそうです。繰り返しの最後がどうなるか確認してみます。

最後の繰り返しが始まる時は、I=8、A=8、C=7、D=8 となっています。

Int(Z÷10^(D-I)→C

は、Int(8÷10^(8-8)) つまり、Int(8-10^(0)) です。100 = 1  (ゼロ乗は1)なので、

C8 が代入され、正しいことが分かります。

次に、Locate コマンドの表示は、

Locate X+I-1,Y,CLocate X+7,Y,C なので、これも正しいですね。これは単に右隣に表示させるだけなので、特に確認も不要かも知れません。

これで、必要な処理は終わりですが、プログラム上は、

Z-C10^(D-I)→Z

があります。ここで求めた Z はこれ以上使わないので、これがエラーにならなければOKです。そこで、具体的に数値を当てはめると、

8 - 8 x 10^(8-8) = 8- 8x 10^(0) = 8 - 8 = 0

となり、エラーにはならないことが確認できました。

以上をまとめておくと、

Int(log(Z))+1→D

For 1→I To D
Int(Z÷10^(D-I))→C
Locate X+I-1,Y,C
Z-C10^(D-I)→Z
[必要ならコンマを表示]
Next


3桁区切り文字を追加表示する

3桁区切り文字であるコンマは、基本的には3桁ごとですが、最初だけ違います。
例えば、12345678 は、12,345,678 となるので、最初の 12 の2桁の後コンマを追加する必要があります。その後は3桁ごとです。

今回は、繰り返しが何回目がを示す変数 I をうまく使ってみます。

12345678 の場合、最初にコンマを追加すべきかどうかは、この数値の桁数、つまり8桁を3で割った余りで判別できそうです。
8を3で割った余りは2です。つまり、頭から2桁まで表示したら、つまり繰り返しが2回目の時、コンマを追加すれば良いですね。
次にコンマを打つべきタイミングは、繰り返し回数を3で割って余りが2の時、つまり5回目の繰り返しの時です。

I を3で割った時の余りを計算するには、

fx-5800P で Mod を使いたい - 逆引きCasio Basic を参照してください。Mod 関数は fx-9860GII のCasio Basic に備わっている「余りを求める」関数ですが、fx-5800P にはありません。

I を3で割った時の余りは、

I-3Int(I÷3)

で得られます。

なお、最初に Z の値、例として 12345678 を3で割った余りを計算して、変数 F に入れておくことにします。繰り返し処理のたびに、I を3で割った余りが F と同じなら、コンマを追加すれば良いですね。

変数 F を計算するコードは、

D-3Int(D÷3)→F

です。これを繰り返しの For 文の前に置いておく必要があります。

その上で、必要に応じてコンマを追加表示するプログラムは、

If I-3Int(I÷3)=F
Then
Isz X
Locate X+I-1,Y,","
IfEnd


です。

この5行を [必要ならコンマを表示] と置き換えれば、うまくゆきそうです。

ここで、Isz X は、X を1つ増やすという Casio Basic 旧来の命令です。
X+1→X 
でも問題ありませんが、Isz X の方が実行速度が速いので、これを採用します。
これを追加したのは、コンマを表示すれば、その後の表示桁 X+I-1 が全て右に1個ずれるので、X 自体を1個増やしておけば良いという意味です。

繰り返し処理は、最後の繰り返しでエラーにならないか、期待しない動作をする可能性を確認することが、大切です。上でも最後の繰り返しを確認しました。コンマの表示部分も、最後の繰り返しの時を検証してみます。

繰り返しの最後は、I=8 になっているので、I を3で割った余りが2になります。F は2なので、等しくなります。
すると、

If I-3Int(I÷3)=F 

は、If の条件を満たすので、コンマを追加表示します。

これで良いでしょうか?

最後にコンマを追加すると、

12,345,678,

となって問題があります。そこで、繰り返しの最後だけは Locate コマンドでコンマを表示しないようにしたいですね。逆に言えば、繰り返し回数が 桁数 D より小さい時だけ Locate コマンドでコンマを表示すれば良いわけです。
具体的には、以下のようにします。

I<D⇒Locate X+I-1,Y,","

とします。

は旧来の命令です。これについては、以下のコマンドリファレンスを参照してください。

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


なお、上記の  命令を使った表記は、

If I<D
Then Locate X+I-1,Y,","
IfEnd


といしても良いのですが、If よりも 命令の方が動作が速く、式1つを実行するだけなので ⇒ が使えすので、こちらを採用します。結果的に 命令を使った方が表記も完結で見やすくなりますね。

コンマを表示するために追加した部分を赤文字で示すと、プログラムは以下のようになります。


ファイル名: 3DIGIT
Int(log(Z))+1→D
D-3Int(D÷3)→F

For 1→I To D
Int(Z÷10^(D-I))→C
Locate X+I-1,Y,C
Z-C10^(D-I)→Z
If I-3Int(I÷3)=F
Then Isz X
I<D⇒Locate X+I-1,Y,","
IfEnd

Next



サブルーチンの動作を確認する

このサブルーチン 3DIGIT は、予め以下のような使い方を決めています。

=====
例えば、金額 B (元本) を3桁区切りで表示させるため(X=5, Y=1と指定されているとして)、

Locate X,Y,B

の代わりに、

B→Z:5→X:1→Y
Prog "3DIGIT"


と記述する。
=====

サブルーチンの動作確認のために、わざわざメインルーチンから呼び出すのも良いですが、サブルーチンだけで確認した方が良いと思います。

そこで、メインルーチンで予め設定される変数を、サブルーチンの一番最初で設定して、サブルーチンだけを動作すれば動作確認ができますね。

今回は、動作確認のために、予め設定される変数 ZXY を設定するために、以下のように赤文字のコードを追加しておきます。


ファイル名: 3DIGIT
12345678→Z
5→X
1→Y
""
Int(log(Z))+1→D
D-3Int(D÷3)→F

For 1→I To D
Int(Z÷10^(D-I))→C
Locate X+I-1,Y,C
Z-C10^(D-I)→Z
If I-3Int(I÷3)=F
Then Isz X
I<D⇒Locate X+I-1,Y,","
IfEnd
Next



ここで、"" ("" を続けて2回入力)が必要な理由ですが、"" 無しで上のプログラムを実行すると、3桁区切りの数値が表示されるところが一瞬見え、それが消えて、0 (ゼロ)と表示されますね。Casio Basic の仕様として、プログラム終了直前に計算された値がプログラム終了時に表示されます。もしプログラム終了直前に Locate コマンドが実行されるなら、その表示のまま終了します。

上のプログラムでは、プログラム終了直前に A-C10^(D-I)→A が実行されるので、その計算結果 0 が終了時に表示されるわけです。そして、この 0 の表示は、Casio Basic の内部カーソル行の右端に表示される仕様で、入力命令 " " や出力命令 ◢ が実行されると、内部カーソル行は1行づつ下に下がり、最下行に至れば、そのまま最下行のままになります。

つまり、"" は、何も出力せず、内部カーソル行を1行下げる仕事をしています。

"" を付けて、上のプログラムを実行すると、

12,345,678
        0


と表示されます。終了直前の計算値 0 が1行さがって表示されていますね。
そして、肝心の動作確認ですが、問題ありません。

12345678→Z

で、色々と異なった値を A に代入して、動作確認してみてください。

動作確認で問題なさそうなので、頭に追加した4行を消しておきましょう。


3桁区切り表示サブルーチン

ファイル名: 3DIGIT

Int(log(Z))+1→D
D-3Int(D÷3)→F

For 1→I To D
Int(Z÷10^(D-I))→C
Locate X+I-1,Y,C
Z-C10^(D-I)→Z
If I-3Int(I÷3)=F
Then Isz X
I<D⇒Locate X+I-1,Y,","
IfEnd
Next






メインルーチンからサブルーチンを呼び出す

それでは、完成したサブルーチン 3DIGIT を使うために、少し変更して準備していたメインルーチン COMPINT2 をもう一度示します。サブルーチンに呼び出し Prog "3DIGIT" に置き換える予定の3カ所の Locate コマンドを赤文字にしてあります。


ファイル名: COMPINT2

Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


0→B:0→R:0→N:0→T:0→M

Do

0→K:Do
Getkey→K
LpWhile K=0
K=73⇒Break

If K=35
Then
5→X:1→Y:9→D:1→E
Prog "INP":Z→B
Locate X,Y,B
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース9個)
Locate 7,3,T
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース9個)
Locate 7,4,M
IfEnd

LpWhile
 1
Cls
Locate 7,2,"BYE!"



1つめのLocateの置き換え

Locate X,Y,B

を置き換えるには、
直前に変数 X、Y、Z が設定されているので、3DIGIT を呼び出すだけでOKですね。
従って、Locate X,Y,B を以下で置き換えます。

Prog "3DIGIT"


2つめのLocateの置き換え

Locate 7,3,T

を置き換えるには、Z、X、Y を設定した後 3DIGIT を呼び出します。

T→Z:7→X:3→Y
Prog "3DIGIT"



3つめのLocateの置き換え

Locate 7,4,M

を置き換えるには、同様に

M→Z:7→X:4→Y
Prog "3DIGIT"



完成に近づいたプログラムをまとめます。

ファイル名: COMPINT2
Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


0→B:0→R:0→N:0→T:0→M

Do

0→K:Do
Getkey→K
LpWhile K=0
K=73⇒Break

If K=35
Then
5→X:1→Y:9→D:1→E
Prog "INP":Z→B
Prog "3DIGIT"
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース9個)
T→Z:7→X:3→Y
Prog "3DIGIT"
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース9個)
M→Z:7→X:4→Y
Prog "3DIGIT"

IfEnd

LpWhile
 1
Cls
Locate 7,2,"BYE!"



完成にはもう一息です。実際に実行してみると、表示に問題が出てきます。




表示の不備を修正

入力桁数と出力桁数が違う

コンマが追加されるのて、3桁区切りの出力桁数は必ず入力桁数以上になります。
そこで、サブルーチン 3DIGIT により3桁区切りを行う前には、コンマが増えた分だけ多くのスペースで消去する必要があります。

1-C: の右の入力については、以下のように空白で画面の右端まで消去します。

If K=35
Then
5→X:1→Y:9→D:1→E

Locate X,Y,"      " (スペース11個)
Prog "INP":Z→B
Prog "3DIGIT"



TOTALMONTH の右の入力については、Prog "3DIGIT" の前で空白で消去すれば良いですね。

Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース10個)
T→X:7→X:3→Y
Prog "3DIGIT"

Int(T÷N÷12)→M
Locate 7,4,"     " (スペース10個)
M→Z:7→X:4→Y
Prog "3DIGIT"




ここまでに作ったプログラムを示します。

ファイル名: COMPINT2
Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


0→B:0→R:0→N:0→T:0→M

Do

0→K:Do
Getkey→K
LpWhile K=0
K=73⇒Break

If K=35
Then
5→X:1→Y:9→D:1→E
Locate X,Y,"      " (スペース11個)
Prog "INP":Z→B
Prog "3DIGIT"
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース10個)
T→Z:7→X:3→Y
Prog "3DIGIT"
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース10個)
M→Z:7→X:4→Y
Prog "3DIGIT"

IfEnd

LpWhile
 1
Cls
Locate 7,2,"BYE!"





最後の仕上げ - エラーの修正

プログラムを実行してみましょう。

1-C: の右には、最大9桁まで入力可能なので、123456789 を入力してみあす。

9digit_input1 

そして、[EXE] キーで入力を確定すると、3桁表示されますが...

9digit_input2 

一番右の桁の 9 がビジーマーカーに半分隠れてしまって、見づらくなっています。

それだけなら良いのですが、2-R: と 3-Y に値を入力すると、エラーになってしまいます。

Argument_ERROR 

123456789 を3桁区切りで表示すると

TOTAL 123,456,789

となり、この行は17文字になります。1行は16桁しかなく、16桁を超える表示を Locate で行うのでエラーになります(仕様です)。


そこで、1-C: の右の入力桁を最大8桁に修正します。


[2016/07/16] 追加修正

1-C: の右に入力する際、[1] キーを押し、そのまま何も入力せず [EXE] キーを押すとエラーになります。
何も入力しないで [EXE] キーを押すと、サブルーチン INP が終了する際に変数 Z0(ゼロ)が入ります。 すると、続いて実行されるサブルーチン 3DIGIT で、上から2行目にある Int(log(Z))+1→D でエラーになります。

というのは、Int(log(Z))+1→Dlog(Z) でエラーとなります(log( ) の仕様です)。

従って、サブルーチン 3DIGIT の冒頭で、Z0(ゼロ)ならばスグにサブルーチンを終了させるように変更するために、冒頭に

Z=0⇒Return

を追加します。

ファイル名: 3DIGIT
Z=0⇒Retuen
Int(log(Z))+1→D
D-3Int(D÷3)→F

For 1→I To D
Int(Z÷10^(D-I))→C
Locate X+I-1,Y,C
Z-C10^(D-I)→Z
If I-3Int(I÷3)=F
Then Isz X
I<D⇒Locate X+I-1,Y,","
IfEnd
Next


===== 追加修正はここまで =====


今回は、これで完成とします。



ファイル名: COMPINT2
Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


0→B:0→R:0→N:0→T:0→M

Do

0→K:Do
Getkey→K
LpWhile K=0
K=73⇒Break

If K=35
Then
5→X:1→Y:8→D:1→E
Locate X,Y,"      " (スペース11個)
Prog "INP":Z→B
Prog "3DIGIT"
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース10個)
T→Z:7→X:3→Y
Prog "3DIGIT"
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース10個)
M→Z:7→X:4→Y
Prog "3DIGIT"

IfEnd

LpWhile
 1
Cls
Locate 7,2,"BYE!"



ただし、1-C: の右に、例えば 87654321 と8桁を入力して、TOTALMONTH を表示させると、2-R:3-Y: の値がそれほど大きくなくても、上と同じ理由で Argument ERROR が発生します。エラーを完全に封じ込めるには、1-C: の入力桁数を7桁や6桁に制限すれば良いのですが、ここで元本として 6千万円程度までなら殆ど問題無いので、ここでは桁数を減らすことはしないでおきます。



3桁区切り表示用のサブルーチンについて、sentaro様から表示が速くなるロジックを提案頂きました。次回は、これを紹介致します。



つづく...

Casio Basic入門53Casio Basic入門G01 / 目次




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

人気ブログランキングへ


FC2ブログランキングへ



 



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

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




関連記事

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

Casio Basic入門51

Casio Basic入門
<目次>

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

修正 2016/07/17

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

Chapter 9 - 初級

前回: Casio Basic入門50 を見る


◆ Chapter 9 の目標: 簡単な換算プログラム - 入力ボックスの活用


Chapter 9-1 
fx-5800P で複利計算プログラムを作る

Chapter 7 から Chapter 8 では、fx-5800P で温度換算プログラムを作り、さらに当ブログオリジナルの汎用サブルーチン「入力ボックス 2.0」を使って、より使いやすいにプログラムに改造しました。ここで取り上げたプログラムは、わざわざ入力ボックス 2.0 を使わなくても、そこそこ使えるプログラムでした。

fx-5800P プログラムライブラリ - 入力ボックス

そこで、今回は入力ボックス 2.0 を使わなければ実現できない換算プログラムを、簡単に作ってみます。入力ボックスの使い方のツボも併せて紹介します。

後半は、桁数の大きな数を3桁区切りで表示する機能を追加してみます。



プログラムのコンセプトと画面構成

今回作ってみるのは、複利計算プログラムで、ローンを借りる時、元金、利率(年利)、返済期間(年)を入力すると、返済総額、月々返済額を表示します。

画面構成を示します。以下は実際に作ったプログラムの画面ですが、作る前は頭の中でこの画面構成を想像することから始まります。何度もプログラムを作っていると、さほど難しいことではないと思います。

CompInt_1 

ここでは、16桁 x 4行の画面に収めるために、各項目を省略記号で表示します。あとで簡単に分かる記号なら何でも良いのですが、ここは私の好みで以下のようにしてみました。

1-C: (元金) ... Capital から C としました。

2-R: (年利、%) ... Interest Rate から R としました。

3-Y: (返済期間、年) ... Year から Y としました。

TOTAL (返済総額) 

MONTH (月々返済額)


例えば、1400万円のローンの場合、
1) 年利1.2%、返済10年
2) 年利0.95%、返済8年
の比較をしてみると、以下のような結果になります。

CompInt_8 CompInt_13 

このプログラムは、画面スクロールしないので、元金、年利、返済期間のどれかを変更すると、返済総額や月々返済額がどのように変わるかが、見やすいことがポイントです。

1-C: (元金)は、9桁を最大としていますが、10億円で9桁なので十分でしょう。[1]キーを押すと9桁の入力ボックスが現れ、そこに 14000000 を入力します。

2-R: (年利、%) を 1.2 から 0.95 に変える場合、[2] キーを押すと、入力ボックス >>>> (4桁) が現れ、そこに 0.95 と入力しますが、ここでは画面構成が崩れず、画面がスクロールしません。これが、入力ボックスを使うメリットです。Casio Basic の旧来の命令(入力命令 ? や出力命令 )を使えば、必ず画面スクロールするので、変化を比較しにくくなります。

CompInt_9 


ちなみに、旧来の命令を使うと入力時にスクロールして画面構成が崩れる実例、その対応について以下で具体的に紹介しています。

Casio Basic入門43

旧来の命令は多彩な機能が盛り込まれていて利便性が高いので、プログラミングが楽になりますが、画面構成を自分で思い通りにできません。そこで、Casio BasicのBasicコマンドを使うことで、旧来の命令を置き換えられることを上記の記事から始まる Chapter 8 で紹介しています。余裕があれば、一度ご覧ください。




ここでは、ファイル名を COMPINT とします。 「複利」は、Compound Interest なので、 COMP + Int で COMPINT です。
FUKURI など好きなプログラム名で大丈夫です。

変数を決める

さて、このプログラムで使う変数を決めます。

1-C: (元金)に、変数 C を使おうと思ったのですが、変数 C は入力ボックスが動作するとその値が変化するので、別の変数にする必要があります。そこで、借入金 = Borrowed Money なので、変数 B を使うことにします。
fx-5800P プログラムライブラリ - 入力ボックス を参照すれば、このように変化する変数を書いてありますので、参考にしてください。

2-R: (年利、%)には、そのまま R を使うことにします。

3-Y: (返済期間、年)に Y を使おうと思いましたが、変数 Y は入力ボックスの表示位置を指定するために使うので、代わりに N を使うことにします。

以上、1 ~ 3 は、[1][3] キーで入力項目を選びます。

TOTAL (返済総額)には、T を使うことにします。

MONTH (月々返済額)には、M を使うことにします。



複利計算方法

本来なら、ボーナス払いなどを含めると現実的なプログラムになりますが、ここでは簡単にするために均等払いを前提にします。
また、実際のローン契約には、金利以外に種々な手数料があって、それらを含めた実質金利が使われますが、プログラムを簡単にするために、表面金利で計算を簡単にします。

最も簡単な複利計算は、

返済総額 T = B x (1 + R/100)N

となり、これを採用します。但し円単位なので、小数以下は切り捨てにすることにします。

Casio Basic では、以下のようにして T を計算します。

Int(B(1+R÷100)^(N))→T

月々返済額 M = T/N/12

なので、Casio Basic では、以下で M を計算します。これも円単位なので、小数以下は切り捨てます。

Int(T÷N÷12)→M

この複利計算プログラムは、条件を色々と変えてみて、自分に合った総額や毎月の負担を概算比較するのが目的なので、正確さよりもわかりやすさを優先させます。従って、小数点以下を切り捨てて問題無いと決めます。切り捨ての代わりに四捨五入でも良いと思いますが、少数ではなくて整数を表示することを優先させることにします。



プログラム構造

プログラム全体の方針として、以下のプログラム構造で作り始めることにします。

[初期画面表示]

[変数の初期化]

Do

 [入力]

 [計算と数値表示]

LpWhile 1





具体的なプログラミング

では、上のプログラム構造で具体的に作ってみましょう。

初期画面表示

以下のような画面を初期表示します。

CompInt_1 

Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


特に難しいところは無いと思います。


変数の初期化

変数 B、R、N、T、M を全て 0 で初期化します。

0→B:0→R:0→N:0→T:0→M


入力

おそらく、ここが今回のプログラムの中心になると思います。

この部分のプログラム構造を決めます。


[入力したキーを調べる]

If
押したキーが[1]ならば 
 1-C: の右に9桁の入力ボックスを表示し、入力値を変数 B に格納する

Else If
押したキーが[2]ならば、
 2-R: の右に4桁の入力ボックスを表示し、入力値を変数 R に格納する

Else If
押したキーが[3]ならば、
 3-Y: の右に3桁の入力ボックスを表示し、入力値を N に格納する

IfEnd:IfEnd
IfEnd


入力したキーを調べる

Getkey コマンドを使って、押したキーのキーコードを調べれば良いので、以下のようにします。

0→K:Do
Getkey→K
LpWhile K=0


何もキーが押されない時は、Getkey は 0 を返すので、変数 K は 0 のままで、K が 0 であれば Do ループを継続します。
従って、この Do ループに入る前に、K を 0 で初期化しておく必要があります。

何かキーが押されたら、K にはそのキーのキーコードが入り、K が 0 でなくなるので、Do ループを終了して、プログラムは下へ進みます。

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


入力されたキーに従って、数値を入力させる

fx-5800P では、[1]キーのキーコードは 35[2]キーのキーコードは 36[3]キーのキーコードは 37 です。
従って以下のコードになります。

If K=35
Then
 
[1-C: の右に9桁の入力ボックス]
Else If K=36
Then
 
[2-R: の右に4桁の入力ボックス]
Else If K=37
Then
 
[3-Y: の右に3桁の入力ボックス]
IfEnd:IfEnd
IfEnd



ここで使う入力ボックスは、0以上の少数入力に対応した INP を使うことにします。

fx-5800P プログラムライブラリ - 入力ボックス 参照。

入力ボックスの使い方は、、

[入力ボックスの表示位置、桁数、インジケータの設定]
Prog "INP"
[入力値の取得]


となります。

入力ボックスの表示位置は、変数 XY で指定します。
入力ボックスの桁数は、変数 D で指定します。
入力ボックスのインジケータの種類は、変数 E で指定します。

そして、入力ボックスで入力された値は変数 Z に格納されているので、Zの値を それぞれ変数 B, R, N に代入します。

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

具体的には、以下になります。


1-C: の右に9桁の入力ボックス

5→X:1→Y:9→D:1→E
Prog "INP"
z→B



2-R: の右に4桁の入力ボックス

5→X:2→Y:4→D:1→E
Prog "INP"
Z→R



3-Y: の右に3桁の入力ボックス

14→X:2→Y:3→D:1→E
Prog "INP"
Z→N



以上をまとめると、入力ブロックは以下になります。

0→K:Do
Getkey→K
LpWhile K=0

If K=35
Then
5→X:1→Y:9→D:1→E
Prog "INP":Z→B
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd


計算と数値表示

返済総額と月々返済額の計算は、上で紹介しています。

その結果を表示するには、既に表示されている数値をスペースで上書きして消した後、表示します。

Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース9個)
Locate 7,3,T
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース9個)
Locate 7,4,M



但し、これだけだとたまにエラーが発生します。
返済期間 N が 0 の時、T÷N÷12 の計算で、0で割り算するエラーです。

そこで、N が0の時は、上の計算を行わないようにすれば良いですね。

さらに、3つの条件、つまり 元本 B、年利 R、返済期間 N のいずれかが 0 (ゼロ)の時は、上の計算と表示を行わない方が良いと思います。
というのも、プログラムを起動した直後は、3つの条件全てが空欄になっていて、順に入力してるとき、空欄が1つでもあれば、TOTALMONTH に表示しないのが良いでしょう。そこでプログラムを変更してみます。

色々な方法がありますが、記述量の少ない方法の1つとして、BRN のいずれかが 0 でない時、言い換えれば B x R x N0 でない時に、計算と表示を行うようにプログラムを変更します。

BRN が 0 でない時 [...] を実行させるのは、

If BRN
Then
[...]
IfEnd

と書けば良いですね。
If の後に来るのは判定条件ですが、[判定条件] が正しい時、あるいは 0 でない時に、Then 以下を実行するのが、If 文の仕様です。

計算と数値表示のブロックは以下のようになります。

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース9個)
Locate 7,3,T
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース9個)
Locate 7,4,M
IfEnd





目標のプログラム

目標のプログラムが完成しました。

ファイル名: COMPINT
Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


0→B:0→R:0→N:0→T:0→M

Do

0→K:Do
Getkey→K
LpWhile K=0

If K=35
Then
5→X:1→Y:9→D:1→E
Prog "INP":Z→B
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース9個)
Locate 7,3,T
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース9個)
Locate 7,4,M
IfEnd

LpWhile 1



今回の複利計算プログラムも換算プログラムの一種です。換算プログラムは、だいたい似たようなプログラム構造で書けます。

逆に言えば、今回のように大まかなプログラムの構造を考え、それに従って細かいところを書けば、換算プログラムは慣れれば色々と作りやすいと思います。

入力ボックスの利点と注意点もお分かりだと思います。




仕上げ

実は、fx-5800P を持っている知り合いがローンの組み替えを検討していたので、そのために作ったものです。

基本的な機能には関係ありませんが、ちょっとだけ変更して、仕上げを行いました。

まず、[EXIT] キーを押してプログラム終了できるようにしました。これはご本人の希望でした。ついでにプログラム終了時に、画面に BYE! と表示するようにしてみました。

このプログラムでは、Getkey でキーコードを取得しているので、[EXIT] キーを押せば、そのキーコード(73)を取得して、変数 K に格納されています。

[以下 2016/07/18 修正]

これを利用して、K=73 の時、Do ループから外へ抜けるようにします。

入力したキーを調べる内側の Do ループの直後に、

K=73⇒Break

を追加します。K73 の時は、強制的に Do ループから抜けて、一番下の LpWhile 1 の次までジャンプします。


そして、最後の LpWhile 1 の下に、一旦画面をクリアして (Cls) から、BYE! を表示するように追加しました。


ファイル名: COMPINT
Locate 1,1,"1-C:"
Locate 1,2,"2-R:"
Locate 10,2,"3-Y:"
Locate 1,3,"TOTAL"
Locate 1,4,"MONTH"


0→B:0→R:0→N:0→T:0→M

Do

0→K:Do
Getkey→K
LpWhile K=0
K=73⇒Break

If K=35
Then
5→X:1→Y:9→D:1→E
Prog "INP":Z→B
Else If K=36
Then
5→X:2→Y:4→D:1→E
Prog "INP":Z→R
Else If K=37
Then
14→X:2→Y:3→D:1→E
Prog "INP":Z→N
IfEnd:IfEnd
IfEnd

If BRN:Then
Int(B(1+R÷100)^(N))→T
Locate 7,3,"     " (スペース9個)
Locate 7,3,T
Int(T÷N÷12)→M
Locate 7,4,"     " (スペース9個)
Locate 7,4,M
IfEnd

LpWhile 1 
Cls
Locate 7,2,"BYE!"



これで、fx-5800P で動作する複利計算プログラムができました。

ボーナス払いなどの場合に対応するなど、改造してみては如何でしょうか?



次回は、このプログラムをさらに見やすくなる工夫をしてみようと考えています。



つづく...

Casio Basic入門52Casio Basic入門G01 / 目次




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

人気ブログランキングへ


FC2ブログランキングへ



 



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

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




関連記事

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

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

やす (Krtyski)

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


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

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

なお管理人はカシオ計算機の関係者ではなく、Casio Basicが面白いと感じる1ユーザーです。

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


人気ブログランキングへ


FC2ブログランキングへ


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

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

この人とブロともになる

QRコード
QR