Casio Basic入門27

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

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

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門26 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回は、ドイツ時間を夏時間や標準時間に切り替える機能、それに伴って正しい時間を表示する機能を追加しました。
今回は、前回とほど同様の方針で、LA時間を夏時間に切り替える機能を追加してゆきます。


今回完成させるプログラムを一番下に掲載しているので、先にそれを見て、分かれば先に進んでも良いでしょう。



Chapter5-5
少し異なるルーチンを、わかりやすく追加する(2)

ロサンゼルス時間の夏時間切り替え機能をメニュー番号4にします。同時に、現在は夏時間なのか、標準時間なのかを表示するようにします。

今回は、以下のように 2:PST の右に LA時間の夏時間l設定用のメニューを追加します。

39-TZ5_main    


標準時間を ST、夏時間を DL と表示することにしています。
ST は Standard Time (標準時間) の略で、DL は Daylight Saving (アメリカ流の夏時間の表現) からとっています。

上の画面は、起動時の初期表示で、起動時には標準時間となるようにします。そして、[4] キーを押したら夏時間に切り替わり、もう一度押したら標準時間に戻る...といった動作(トグル動作)にします。

プログラム内部で、現在がLAの夏時間かどうかがわかるようにするために、新しい変数 T を夏時間フラグとして用い、

T = 0 時は標準時間で、T = 1 の時は夏時間

と決めます。


今回は、[4] キーを押してLA時間を夏時間に変更し、ロサンゼルス時間を計算し、その結果を画面表示する機能を追加します。

1.初期化処理
先ず、今回追加する新しい変数 T (ヨーロッパの夏時間フラグ)の初期化を行う。
次に、初期表示の変更を行います。初期表示はサブルーチン TZM で受け持っているので、これを修正する。

2.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[4] キーが押された時、メニュー変数 M4 を入れる。
なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態になる。

3.入力処理
M=4 の時は、キー入力処理は行なわない。但し、LA時間 U が、夏時間か標準時間に変更されるので、U から「時」と「分」を分離する。

4.時間の計算
M=4 の時、変更されたLA時間を計算する。日本時間とドイツ時間には影響が無いので、これらの計算は行わない。

5.時間表示の更新
時間表示サブルーチン TZD を用いるので、これまでのように日本時間、ドイツ時間、LA時間の表示を更新する。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。今回の機能追加に必要な修正部分がはっきりします。

[初期設定]

Prog "TZM"  [メイン画面表示]

While 1

  [メニュー番号取得処理]

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [LA時間入力処理] (時間から「時と「分」の分離も行う)
  Else If M=3:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  Else If M=4:Then
    キー入力処理は行わない。時間から「時」と「分」の分離のみ行う
  IfEnd:
IfEnd
  IfEnd:IfEnd
  IfEnd

  If M=0:Then
    [時間計算]
  Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  Else If M=3:Then
    [時間計算]
  Else If M=4:Then
    [時間計算]
  IfEnd:
IfEnd
  IfEnd:IfEnd
  IfEnd

  Prog "TZD"  
[時間の再表示]

WhileEnd


(赤文字は追加・修正部分)



1.初期化処理
今回は、ドイツの夏時間フラグ T を追加したので、これを 0 で初期化しておきます。
T = 0 は、標準時間であることを示します。

0→T

を追加します。



2.メニュー番号取得処理


[4] キーを押すと、メニュー変数 M に 4 を設定する。

メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M 
[今回追加]


[4] キーのキーコードは 21 です。




3.入力処理

ドイツ時間を、夏時間 - 標準時間 に切り替えるのみで、キー入力処理は行いません。ドイツ時間が切り替わっても、日本時間やロサンゼルス時間には影響が無いので、この時点での日本時間 J を分離して、「時」を 変数 A に、「分」を変数 B に入れておきます。

Int(J÷100)→A
J-100A→B"


この部分は、M = 3 の時のドイツの夏時間設定と同じなので、Else If M=4IdEnd を追加せずに、以下のようにします。

Else If M=3
Then
Int(J÷100)→A
J-100A→B
IfEnd


この部分を以下のように修正します。

Else If M=3 Or M=4
Then
Int(J÷100)→A
J-100A→B
IfEnd


Or M=4 を追加するだけです。



4.時間計算

最初に、今回追加するプログラムを示します。

Else If M=4
Then
If T:Then
0→T:Q+1→Q
Else
1→T:Q-1→Q
IfEnd
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZM"
IfEnd


ドイツの夏時間計算のルーチンで、P を Q に置き換え、G を U に置き換えるだけです。つまり、基本ロジックは全く同じです。

一応、説明をします。

最初の部分は、夏時間フラグの変更と時差の変更を行います。

  If T:Then
  0→T:Q+1→Q
  Else
  1→T:Q-1→Q
  IfEnd


現状が夏時間の時は、T=1 になっています。
  If T:Then
は、T1 の時の分岐処理なので、
夏時間フラグ:0 にし、時差:Q を1時間増やします。

Else 以下は、現状が標準時間の時の処理で、
夏時間フラグ:T1 にし、時差:Q を1時間減らしています。


この後に続く処理では、LA時間を計算し、時間表示サブルーチン TZM を呼び出します。

  A-Q→C
  C<0⇒C+24→C
  100C+B→U
  Prog "TZM"


入力処理のところで、現在の日本時間 J から「時」:A と「分」 B を算出しています。
LA時間は、日本時間の「時」 A と時差 から計算するので、A - Q でLA時間の「時」が得られます。

この計算の結果が負の数になる場合は、LAはまだ前日と言うことになります。この場合は、得られた負の数に 24 を足せば、24時制の「時」になります。

そこで、A - Q を一旦変数 C に入れておき、それが負の数なら 24 を足しておきます。
   A-Q→C
   C<0⇒C+24→C


LA時間:U は、100C + B で計算できます。
   100C+B→U 

最後に、サブルーチン TZM を呼び出す
   Prog "TZM"


さて、画面表示サブルーチン TZM をLAの夏時間に対応するように変更します。

サブルーチン TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"


If S:Then
Locate 5,2,"ST"   
[1:CET を 1:CEST に表示を切り替える]
Locate 15,2,"DL"  
[3:ST を 3:DL に表示を切り替える]
Else
Locate 5,2,"T "   
[1:CEST を 1:CET に表示を切り替える]
Locate 15,2,"ST"  
[3:DL を 3:ST に表示を切り替える]
IfEnd


If T:Then
Locate 4,3,"D"    
[2:PST を 2:PDT に表示を切り替える]
Locate 15,3,"DL"  
[4:ST を 4:DL に表示を切り替える]
Else
Locate 4,3,"S"    
[2:PDT を 1:PST に表示を切り替える]
Locate 15,3,"ST"  
[4:DL を 4:ST に表示を切り替える]
IfEnd


(赤文字は追加分)

アメリカの標準時間と夏時間の略称は、以下のように共に3文字です。

そこで、略称の2文字目を T と D で切り替えると、標準時間と夏時間の略称表示を切り替えられ、上のプログラムをこれを実行しています。

タイムゾーン標準時間 夏時間 
太平洋時間PSTPDT
山岳部時間MSTMDT
中央部時間CSTCDT
東部時間ESTEDT



5.時間の再表示


時間の再表示は、サブルーチン TZD で行います。これについては変更の必要がありません。

サブルーチン TZD のプログラム
J=-1⇒Return

Locate 8,1,"000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム
8→P:17→Q
-1→J:0→G:0→U
0→S:0→T
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
K=21⇒4→M

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
Else If M=3 Or M=4
Then
Int(J÷100)→A
J-100A→B
IfEnd:IfEnd
IfEnd:IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
Else If M=4
Then
If T:Then
0→T:Q+1→Q
Else
1→T:Q-1→Q
IfEnd
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZM"

IfEnd:IfEnd
IfEnd:IfEnd
IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 13,3,"4:"
Locate 1,4,"<AC>:QUIT"

If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd

If T:Then
Locate 4,3,"D"
Locate 15,3,"DL"
Else
Locate 4,3,"S"
Locate 15,3,"ST"
IfEnd




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示):変更なし
J=-1⇒Return

Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、ロサンゼルスの夏時間設定機能を追加しました。
次回は、ヨーロッパのタイムゾーンを変更できるように、機能追加を行います。



つづく...


Casio Basic入門28 / 目次




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


 


keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



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

Casio Basic入門26

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

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

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門25 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回は、日本時間、ドイツ時間、LA時間のいずれかを入力すると、換算したそれぞれの時間を表示するところまで作りました。
今回は、ドイツ時間を夏時間や標準時間に切り替える機能、それに伴って正しい時間を表示する機能を追加してゆきます。

今回までで完成させるプログラムを一番下に掲載しているので、先にそれを見て分かれば、先に進んでも良いでしょう。



Chapter5-4
少し異なるルーチンを、わかりやすく追加する

今回は、ドイツの夏時間切り替え機能をメニュー番号3にします。同時に、現在は夏時間なのか、標準時間なのかを表示するようにします。

具体的には、以下のように 1:CET の右に ドイツ時間の夏時間設定用のメニューを追加表示します。

38-TZ4_main   


標準時間を ST、夏時間を DL と表示することにします。
ST は Standard Time (標準時間) の略で、DL は DayLight saving (アメリカでの夏時間の表現) からとりました。

上の画面は、起動時の初期表示で、起動時には標準時間となるようにします。そして、[3] キーを押したら夏時間に切り替わり、もう一度押したら標準時間に戻る...といった動作(トグル動作)にします。

プログラム内部で、現在がドイツの夏時間かどうかがわかるようにするために、新しい変数 S を夏時間フラグとして用い、

S = 0 時は標準時間で、S = 1 の時は夏時間

と決めます。


今回は、[3] キーを押してドイツ時間を夏時間に変更し、ドイツ時間を計算し、その結果を画面表示する機能を追加します。

1.初期化処理
先ず、今回追加する新しい変数 S (ヨーロッパの夏時間フラグ)の初期化を行う。
次に、初期表示の変更を行います。初期表示はサブルーチン TZM で受け持っているので、これを修正する。

2.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[3] キーが押された時、メニュー変数 M に 3 を入れる。
なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態にする。

3.入力処理
M=3 の時は、入力処理は行なわない。但し、ドイツ時間 G が、夏時間か標準時間に変更されるので、G から「時」と「分」を分離する。

4.時間の計算
M=3 の時、変更されたドイツ時間を計算する。日本時間とロサンゼルス時間には影響が無いので、これらの計算は行わない。

5.時間表示の更新
時間表示サブルーチン TZD を用いて、これまでのように日本時間、ドイツ時間、ロサンゼルス時間の表示を更新する。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。今回追加・修正するところがはっきりと分かります。

[初期設定]

Prog "TZM"  [メイン画面表示]

While 1


   [メニュー番号取得処理] 

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [ロサンゼルス時間入力処理] (時間から「時と「分」の分離も行う)
  
Else If M=3:Then
    入力処理は行わず、時間から「時」と「分」の分離のみ行う
  IfEnd:
IfEnd
  IfEnd:IfEnd

  If M=0:Then
    [時間計算]
  Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  
Else If M=3:Then 
    [時間計算] 

  IfEnd:
IfEnd
  IfEnd:IfEnd

  Prog "TZD"  [時間の再表示]

WhileEnd

(赤文字は追加・修正部分)



1.初期化処理
今回は、ドイツの夏時間フラグ S を追加して、これを 0 で初期化しておきます。
S = 0 は、標準時間であることを示します。

0→S

を追加します。



2.メニュー番号取得処理


[3] キーを押すと、メニュー変数 M に 3 を設定する。

メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M 
[今回追加]


[3] キーのキーコードは 37 です。




3.入力処理

ドイツ時間を、夏時間 - 標準時間 に切り替えるのみで、キー入力処理は行いません。ドイツ時間が切り替わっても、日本時間やロサンゼルス時間には影響が無いので、この時点での日本時間 J を分離して、「時」を 変数 A に、「分」を変数 B に入れておきます。

Else If M=3
Then
Int(J÷100)→A
J-100A→B
IfEnd



4.時間計算

夏時間になると時差が1時間減り、標準時間に戻る時は時差が1時間増えます。
但し、ドイツ時間が変わるだけで、日本時間やロサンゼルス時間は変化しません。

これを具体的にプログラムにすると、以下のようになります。

Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
IfEnd


この中で、以下の部分は、夏時間フラグの変更と時差の変更を行います。

  If S:Then
  0→S:P+1→P
  Else
  1→S:P-1→P
  IfEnd


現状が夏時間の時は、S=1 になっています。
  If S:Then
は、S1 の時の分岐処理なので、
夏時間フラグ:S 0 にし、時差:P を1時間増やします。

Else 以下は、現状が標準時間の時の処理で、
夏時間フラグ:S1 にし、時差:P を1時間減らしています。


この後に続く処理では、ドイツ時間を計算し、時間表示サブルーチン TZM を呼び出します。

  A-P→C
  C<0⇒C+24→C
  100C+B→G
  Prog "TZM"


入力処理のところで、現在の日本時間 J から「時」:A と「分」 B を算出するようにしました。
ドイツ時間は、日本時間の「時」 A と時差 P から計算するので、A - P でドイツ時間の「時」が得られます。

この計算の結果が負の数になる場合は、ドイツはまだ前日と言うことになります。この場合は、得られた負の数に 24 を足せば、24時制の「時」になります。

そこで、A - P を一旦変数 C に入れておき、それが負の数なら 24 を足しておきます。
   A-P→C
   C<0⇒C+24→C


ドイツ時間:G は、100C + B で計算できます。
   100C+B→G 

最後に、サブルーチン TZM を呼び出す
   Prog "TZM"


さて、画面表示サブルーチン TZM をドイツの夏時間に対応するように変更します。

サブルーチン TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 1,4,"<AC>:QUIT"

If S:Then
Locate 5,2,"ST"   [1:CET を 1:CEST に表示を切り替える]
Locate 15,2,"DL"  [3:ST を 3:DL に表示を切り替える]
Else
Locate 5,2,"T "   [1:CEST を 1:CET に表示を切り替える]
Locate 15,2,"ST"  [3:DL を 3:ST に表示を切り替える]
IfEnd


(赤文字は追加分)

下から3行目で表示するのは "T " で、 T の後に空白1文字が付加されていることに注意してください。この空白文字があることで、"ST" と表示されている2文字を"T " で上書きして、 表示を 1:CEST から 1:CET に変更できるわけです。


ヨーロッパの標準時間と夏時間の略称は、以下のように標準時間は3文字、夏時間は4文字の表記になっています。
そこで、略称の2文字目以降を T と ST で切り替えると、標準時間と夏時間の略称表示を切り替えられます。

タイムゾーン標準時間 夏時間 
西ヨーロッパ時間WETWEST
中央ヨーロッパ時間CETCEST
東ヨーロッパ時間EETEEST
極東ヨーロッパ時間FETFEST



5.時間の再表示


時間の再表示は、サブルーチン TZD で行います。これまでに作った 時間表示サブルーチン TZD のソースコードを示します。

サブルーチン TZD のプログラム
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U


プログラムを起動した直後は、以下の画面になっています。

38-TZ4_main 

先に、ドイツを夏時間に切り替えてから、時間を入力しようとします。つまりこの画面で [3] キーを押すと、以下のような画面になってしまいます。

40-TZ5_problem 

日本時間が 0000、ドイツ時間が 1700、ロサンゼルス時間が 0000 となっているのは、明かに異常です。

しかし、プログラムを上から順に見ながら確かめると、この状態ではどの地域の時間も入力していないので、当然このような表示になります。では、何が悪いのか?

要するに、この時点で各地域の時間を表示する意味がありません。むしろ表示してはいけない、と考えます。

仮に、どこかの地域に時間を入力すれば、正しい時間が計算される筈です。試しに、日本時間に 20:00 を設定してみます。

41-TZ5_normal 

正しい時差で、時間が表示されているのが分かります。

どの地域にも時間を入力していない状態、つまりプログラム起動直後の状態では、サブルーチン TZD による時間表示が行われないようにすれば、この問題を解決できます。

このような細かい処理は、メインルーチンを変更するよりも、サブルーチンで対処した方が、プログラムは分かりやすくなるので、TZD をどのように変更すべきかを考えます。


1つの方法として、日本時間の変数 J を -1 で初期化する手があります。プログラムを走らせている時は、J が -1 になることは絶対にありません。と言うのも、INPI は仕様上、負の値を戻すことが無いからです。一回でも、どこかの地域に時間を入力すれば、J0 か正の値になるわけで、-1 は初期状態を示すためだけに使えます。敢えて、J-1 で初期化するのが、今回の作戦です。

言い換えれば、変数 J に、初期状態フラグとしての働きも持たせるわけです。
そこで、サブルーチン TZD では、J の異常値 -1 を検出させて、異常値なら何も動作しないで終了し、メインルーチンに戻るようにします。TZD の最初の行に、以下のコードを追加します。

J=-1⇒Return

Return コマンドは、プログラムを強制終了させます。サブルーチン内では、Return コマンドがあると、そのサブルーチンを直ちに終了させ、メインルーチンに戻ります。
 ⇒ Casio Basicコマンドリファレンス: Return


サブルーチン TZD を以下のように変更します。

サブルーチン TZD のプログラム
J=-1⇒Return

Locate 8,1,"000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U


これに合わせて、忘れずにメインルーチン TZ の [初期化処理] ブロックでの J の初期化を -1→J に変更しておきます。

では、TZ を起動し、いきなり最初に [3] キーを押して、ドイツを夏時間にしてみます。以下のように、時間が表示されないことを確認してください。次に、日本時間を 20:00 にしてみます。ドイツ時間が 1300、ロサンゼルス時間が 0300 になっていれば正常です。

41-TZ5_normal 

では、[3] キーをもう一度押して、夏時間から標準時間へ戻してください。日本時間とロサンゼルス時間は、当然変化なしで、ドイツ時間が 1200 と表示され、プログラムが正しく動作していることがわかります。



今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム
8→P:17→Q
-1→J:0→G:0→U
0→S
Prog "TZM"

While 1

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

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
Else If M=3
Then
Int(J÷100)→A
J-100A→B
IfEnd:
IfEnd
IfEnd:IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
IfEnd:
IfEnd
IfEnd:IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 1,4,"<AC>:QUIT"

If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示)
J=-1⇒Return

Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、ドイツの夏時間設定機能を追加しました。
次回は、ロサンゼルスの夏時間設定を追加してゆきます。



つづく...


Casio Basic入門27 / 目次



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


 


keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



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

Casio Basic入門25

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03

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

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門24


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


前回は、日本時間を入力したら、ドイツ時間とロサンゼルス時間を表示するところまで、作りました。
今回は、ドイツ時間やロサンゼルス時間を入力したら、日本、ドイツ、ロサンゼルスの時間を表示するように、プログラムを書き足してゆきます。

今回完成させるプログラムを一番下に載せているので、それを見て分かれば先に進むのも良いでしょう。



Chapter5-3
同様の機能を追加する

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

35-TZ1_main  

今回追加する機能は、[1] キーを押してドイツ時間 (CET) を入力させ、[2] キーを押してLA時間を入力させ、それぞれの場合に日本時間、ドイツ時間、ロサンゼルス時間を計算し、その結果を画面表示する機能を作ります。


1.初期化処理
新たに追加する変数は、予期しない値にならないように、初期化しておく。

2.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[1] キーが押された時、メニュー変数 M1 を設定する。
さらに、[2] キーが押された時、メニュー変数 M2 を設定する。
なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態にする。

3.入力処理
M=1 の時、入力処理を行い、その結果を ドイツ時間の変数 G に入れる。さらに、G から「時」と「分」を分離する。
M=2 の時、入力処理を行い、その結果をLA時間の変数 U に入れる。さらに U から「時」と「分」を分離する。

4.時間の計算
M=1 の時、入力されたドイツ時間に基づき、日本時間とロサンゼルス時間を計算する。
M=2 の時、入力されたロサンゼルス時間に基づき、日本時間とドイツ時間を計算する。

5.時間表示の更新
日本時間、ドイツ時間、ロサンゼルス時間の表示を更新する。

6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。


メインルーチンの擬似的なプログラムは、以下になります。追加・修正するところが、はっきりと分かります。

[初期設定]

Prog "TZM"  [メイン画面表示]

While 1


   [メニュー番号取得処理] 

  If M=0:Then
    [日本時間入力処理] (時間から「時」と「分」の分離も行う)
  
Else If M=1:Then
    [ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
  Else If M=2:Then
    [ロサンゼルス時間入力処理] (時間から「時」と「分」の分離も行う)
  IfEnd:IfEnd

  IfEnd:

  If M=0:Then
    [時間計算]
  
Else If M=1:Then
    [時差計算]
  Else If M=2:Then
    [時間計算]
  IfEnd:IfEnd

  IfEnd

  Prog "TZD"  [時間の再表示]

WhileEnd

(赤文字は追加・修正部分)


この方針で、プログラムを具体的に書いてゆきます。



1.初期化処理


今回は、ドイツ時間の変数 G とロサンゼルス時間の変数 U を追加します。
前回、J を 0 で初期化したのと同じ理由で、GU0 で初期化しておきます。

0→G:0→U

を追加します。



2.メニュー番号取得処理


[1] キーを押してドイツ時間入力をさせ、[2] キーでロサンゼルス時間を入力させるので、この部分を追加します。

メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M  [今回追加分]
K=36⇒2→M  
[今回追加分]


[1] キーのキーコードは 35 、 
[2] キーのキーコードは 36 です。



3.入力処理

ここで用いる「入力ボックス:INPI 」 については、以下を参照してください。
 ⇒ fx-5800P プログラムライブラリ - 入力ボックス
 ⇒ Casio Basic入門24: 世界時間換算プログラムを作る の Chapter 5-2


ドイツ時間の入力処理
1:CET の右横、(X, Y) = (8, 2) の位置に、4桁の入力ボックスを表示し、小さいインジケータ(▶E)を表示するので、ソースコードは以下のようになります。変数 G は、ドイツ時間を格納する変数です。
省略入力への対応、時間から「時」と「分」を分離する処理は、前回作った日本語入力処理と同様に、サブルーチン: TZC が受け持ちます。

8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
Z→G


ロサンゼルス時間の入力処理
2:PST の右横、(X,Y) = (8, 3) の位置に、4桁の入力ボックスを表示し、小さい確定ガイド(▶E) を表示するので、プログラムは以下のようになります。変数 U は、ロサンゼルス時間を格納する変数です。
上と同様にして、サブルーチン: TZC を使います。

8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
Z→U



以上を追加すると、入力処理は以下のようになります。

メインルーチン [入力処理] ブロックのプログラム
If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
IfEnd:IfEnd

IfEnd


(赤文字は今回追加分)


サブルーチン:TZC のプログラム
If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
IfEnd


(変更はありません)



4.時間計算

メインルーチン TZ に処理を追加します。

M=1 の時、入力したドイツ時間から日本時間とロサンゼルス時間を得る処理
サブルーチン TZC での簡易入力機能の結果、0:05 としたい場合は 2405 と入力する必要があり、その場合は A の値が 24 を超えることになります。

・ドイツ時間:
  - 「時」 = A (サブルーチン TZC で、時間から「時」を分離して得た値)
   但し、A が 24以上になる場合は、24 を引く
   プログラムは、
    A≧24⇒A-24→A
   
となる。
  - 「分」 = B (サブルーチン TZC で得られた値)
  - ドイツ時間: G = 100A + B
   プログラムは、
    100A+B→G 
   
となる。


・日本時間: ドイツ時間に時差 P (8時間) を足す
 - 「時」 = A + P (一旦、変数 C に代入しておく)
  但し、A + P = C が 24以上になる場合は、24 を引く (この場合は日付が変わる)
  プログラムは、
   A-P→C
   C≧24⇒C-24→C
  
となる。
 - 「分」 = B
 - 日本時間: J = 100C + B (サブルーチン TZC で得られた値)
  プログラムは、
   100C+B→J 
  
となる。

・ロサンゼルス時間: 日本時間から時差 Q (17時間) を引く
 - 「時」 = A + P - Q (一旦、変数 C に代入しておく)
  但し、A + P - Q の結果が 0 未満になる場合は、24 を足す (この場合は日付が変わる)
  また、A + P -Q24 以上になる場合は、24 を引く (この場合も日付が変わる)
  プログラムは、
   A+P-Q→C
   C<0⇒C+24→C
   C≧24⇒C-24→C

  
となる。
 - 「分」 = B
 - ロサンゼルス時間: U = 100C + B
  プログラムは、
   100C+B→U
  
となる。

以上のようにして、J (日本時間)、G (ドイツ時間)、U (ロサンゼルス時間) が計算できます。ここまでを、まとめておきます。

日本、ドイツ、ロサンゼルスの時間を計算するプログラム
If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U

Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
IfEnd:
IfEnd


(赤文字は追加分)


M=2 の時、入力したロサンゼルス時間から、日本時間とドイツ時間を得る処理

M=1
の時とほぼ同様の処理となります。

・ロサンゼルス時間:
  - 「時」 = A
   但し、A が 24以上になる場合は、24 を引く (この」場合は日付が変わる)
   プログラムは、
    A≧24⇒A-24→A
   
となる。
  - 「分」 = B
  - ロサンゼルス時間: U = 100A + B
   プログラムは、
    100A+B→U 
   
となる。

・日本時間: ロサンゼルス時間に時差 Q (17時間) を足す
 - 「時」 = A + Q (= C とおく)
  但し、A + Q の結果が 24以上になる場合は、24 を引く (この場合は日付が変わる)
  プログラムは、
   A+Q→C
   C≧24⇒C-24→C
  
となる。
 - 「分」 = B
 - 日本時間: J = 100C + B
  プログラムは、
   100C+B→J 
  
となる。

・ドイツ時間: 日本時間から時差 P (8時間) を引く
 - 「時」 = A + Q - P ( = C とおく)
  但し、A + Q - P の結果が 0 未満になる場合は、24 を足す (この場合は日付が変わる)
  また、A + Q - P が 24 以上になる場合は、24 を引く (この場合も日付が変わる)
  プログラムは、
   A+Q-P→C
   C<0⇒C+24→C
   C≧24⇒C-24→C

  
となる。
 - 「分」 = B
 - ドイツ時間: G = 100C + B
  プログラムは、
   100C+B→G 
  
となる。

以上のようにして、J (日本時間)、G (ドイツ時間)、U (ロサンゼルス時間) が計算できます。ここまでを、まとめておきます。

メインルーチン [時間計算] ブロックのプログラム
If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U

Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
IfEnd:
IfEnd
IfEnd


(赤文字は追加分)



5.時間の再表示


時間の再表示は、サブルーチン TZD で行いますが、特に変更の必要はありません。

サブルーチン TZD のプログラム
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン:TZ のプログラム
8→P:17→Q
0→J:0→G:0→U
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=25⇒1→M
K=36⇒2→M


If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
IfEnd:IfEnd

IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
IfEnd:IfEnd

IfEnd

Prog "TZD"

WhileEnd




サブルーチン:TZM のプログラム (メイン画面表示):変更なし
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 1,4,"<AC>:QUIT"




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示):変更なし
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U




今回は、ドイツ時間やロサンゼルス時間を入力した時の処理を追加しました。
次回は、ドイツ時間の夏時間設定機能を追加してゆきます。



つづく...


CasioBasic入門26 / 目次



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


 


keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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



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

Casio Basic入門24

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2015/07/03

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

Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

前回: Casio Basic入門23 を見る


[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


「世界時間表示プログラム TIME ZONE 」 を実際に作ってゆきます。

Chapter 5 では、以前実際に考えたり作ったりしたことを振り返るために、以前の記事やCasio Basicコマンドリファレンスへのリンクも紹介してゆきます。

プログラムを作る時は、できるだけわかりやすくソースコードを書く ことを心がけます。機能追加が楽になり、バグの発生も少なくなるからです。そして、最初から欲張って多くの機能を盛り込もうとはせずに、全体の骨組みになる部分から作り始めます。その後、徐々に機能を追加するのが確実です。今回は、サブルーチンをうまく使ってゆきます。

そこて、最初に大まかな方針を作ります。


大まかな方針

方針1. スクロールさせずに1 画面内で表示と入力を行う。
  → 入力ボックスを使う

方針2. 最初に、日本・ドイツ・ロサンゼルス(LA)時間の換算プログラムを作り、後から機能追加して夏時間の計算とヨーロッパ・北米のそれぞれのタイムゾーンへの変更と計算をできるようにする。

方針3. ドイツは8時間、ロサンゼルスは17時間だけ日本時間から戻せば(引き算)すれば良い。これは夏時間でない時。

方針4. 時間は24時制を使う。

方針5. 時間は 1024、930 といった整数で扱い、時間を格納する変数には、この整数を入れる。

方針6. 時間表示は、必ず4桁表示とする。例えば 1024、0930、0010 、0004 など、3~1桁の場合は頭に 0 を付加する。4桁に揃えないと、一覧表示が見づらく、勘違いする可能性が増える。

方針7. 大きな骨組みとして、プログラム構造を考える。

 [初期設定] 
 [初期表示]
 While 1
   [メニュー番号取得処理]
   [メニュー番号に応じた入力処理]
   [メニュー番号に応じた時間計算]
   [時間表示の更新]
 WhileEnd


方針8. あとは、実際に作りながら考え、細かいところは必要に応じて変更する。


今回作成するのは、日本時間を入力すると、中央ヨーロッパ時間と北米太平洋時間を表示する機能です。

今回完成させるプログラムを一番下に載せているので、先にそれを見て分かれば先に進むのも良いでしょう。



Chapter5-2
Getkey、入力ボックス、Locate の活用

では、大まかな方針に従って、具体的にプログラムを書いてゆきます。

先ず最初に、日本時間を入力すると、ドイツとロサンゼルスの時間を表示する機能を作ります。

画面デザイン

メイン画面を以下のようにします。

35-TZ1_main   

0:JST
これは日本時間です。[0] キーを押すと日本時間を入力します。項目 1 や 2 で海外の時間を設定した場合は、それに合った日本時間を、ここに表示します。

1:CET
これは、中央ヨーロッパ時間 (Central Europe Time)で、プログラム起動時の初期設定を CET とします(私の好みです...)。[1] キーを押すと CET の時間を入力します。ドイツ、フランス、イタリアなど多くの国がこのタイムゾーンに含まれます。項目 0 や 2 で時間を設定した場合は、それに合った CET 時間がここに表示されます。ドイツが含まれるので、しばらくはドイツ時間と言うことにします。

2:PST
これは、アメリカの太平洋時間 (Pacific Standard Time)で、プログラム起動時の初期設定を PST とします。[2] キーでの入力や表示については、上と同様です。ロサンゼルス(LA)が含まれるので、しばらくはロサンゼルス時間と言うことにします。


この画面を作るプログラムは、以下の通り。

Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 1,4,"<AC>:QUIT"


上の方針で決めたように、後で機能追加する時に、夏時間を設定する機能や、タイムゾーンを変更する機能を追加します。その時、前回紹介したようにタイムゾーンの略称を現地で使われるように変更する予定なので、画面表示を変える必要がでてきます。つまり、上の5行のプログラムは、徐々に複雑になることが予想されるので、画面の表示をサブルーチンにしてメインルーチンから呼び出すようにします。

このようにすると、画面の表示を変える場合でも、メインルーチンを変更せずに済むので、プログラムがわかりやすいままで、バグの発生も抑えられる筈です。

画面表示サブルーチンのファイル名を TZM とします(メイン画面 → MainM なので、TZ + M )。
ちなみに、TZTIME ZONE の略称。

TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 1,4,"<AC>:QUIT"



次に、メインルーチンを作ってゆきます。
メインルーチンのファイル名を TZ とします。TIME ZONE だから、TZ です。

ドイツと日本の時差は、夏時間でない時は8時間、ロサンゼルスとの時差は17時間です。この値は、プログラムで絶対に使うので、変数に入れておきます。ドイツとの時差を変数 P として 8 で初期化、ロサンゼルスとの時差を変数 Q として 17 で初期化します。
8→P:17→Q


ここまでの TZ のプログラム
8→P:17→Q
Prog "TZM"




今回具体的に作るのは、[0] キーを押した時、日本時間 (JST) を入力させ、ドイツ時間とロサンゼルス時間を計算し、その結果を画面表示する機能を作ります。

1.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[0] キーが押された時、メニュー変数 M0 を設定する。なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態にする。

2.入力処理
M=0 の時、入力処理を行い、その結果を 日本時間を格納する変数 J に入れ、0:JST の右に入力した時間を表示する。

3.時差計算
M=0 の時、入力された日本時間に対応したドイツ時間とLA時間を計算する。

4.時間表示の更新
日本、ドイツ、LAの時間の表示を更新する。

5.ループ構造
項目1~4の処理は繰り返し行うので、これらを While 1 ~ WhileEnd ループの中に入れる。


以上を、擬似的なプログラムで表現してみます。

While 1

   [メニュー番号取得処理] (ここで入力待ち)

  If M=0:Then
     [日本時間の入力処理
  IfEnd

  If M=0:Then
     [時間の計算] 
  IfEnd

  [時間表示の更新]


WhileEnd



While 1WhileEnd は無限ループです。PCなどのプログラムでは、無限ループはCPUパワーを無駄に食いつぶすだけでなく、プログラムを正常終了できなくなる可能性もあるので、基本的に使うべきではありません。特に Windows プログラミングでは、できるだけ速やかに制御を Windows (OS) に戻すのが作法です。

しかし、Casio Basic の場合は、[AC] キーを押せば、いつでもプログラムを終了可能で、終了のための特別な処理が不要です。今回は [AC] キーで終了させるようにします。




1.メニュー番号取得処理

Getkeyコマンドの使い方は、以下に詳しく説明していますので、まだよく分からない場合は参照してください。
 ⇒Casio Basic コマンドリファレンス: Getkey
 ⇒Casio Basic入門3: Getkey と Locate コマンドを使いこなす


条件ジャンプの ⇒命令については、以下のコマンドリファレンスや、過去のCasio Basic入門を参考にしてください。
 ⇒Casio Basic コマンドリファレンス: ⇒命令


メインルーチンTZ:メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M


[0] キーのキーコードは 25 です。


ここで、1つ大切な注意点:

最初に、変数 M を -1 で初期化しています。キーコード取得のための Do ループは、K の値が 0 の時ループを継続します。キーコードが 0 と言うのは、キーが何も押されていない状態を示します。

さて、このプログラムを起動する前に、電卓を様々な用途で使うわけで、その際に変数 M に 0 以外の何かの値が入ることが十分有り得ます。

もし、-1で M を初期化しておらず、M に 0 が入っていた場合、[0] 以外の何かキーが押されたことを想定します。その場合、このループを脱出して先に進み、M には想定外の値 0 が入っています。すると、[0]を押していないのに、メニュー番号0が選択されたと誤判定されます。このように想定外の M の値によって、プログラムが意図しない動作をするわけです(要するにバグ)。
そこで、変数 M を完全に把握して制御することで、プログラムを意図に従った動作以外できなくします。

このバグは簡単に発生します。メニュー番号変数 M は、0 以上の整数とするつもりなので、絶対にメニュー番号になり得ない -1 で初期化しておきます。

使う変数は、使う前に初期化をする癖を付けると、バグが入りにくくなってプログラミングが楽になります。



2.入力処理

本プログラム TIME ZONE では、時間を24時制とし、4桁の数字で時間を表すことにしています。
 ・10:24 は、1024
 ・9:30 は、0930
 ・0:20 は、0020
 ・6:00 は、0600
 ・0:05 は、0005


INPI の使い方

入力には、入力ボックス:INPI を使います。
Chapter 3 / Chapter 6 で 入力ボックス:INPI を作りました。その時に作ったプログラムが fx-5800P に残っていない場合は、以下のプログラムライブラリにアクセスし、ソースコードからご自分で fx-5800P に入力するか、CCLファイルをダウンロードして CcLinkerを使って fx-5800P に転送してください。

 ⇒ fx-5800P プログラムライブラリ - 入力ボックス 
入力ボックスは Ver 2.0/2.1 になっており、[Chapter 6 参照]、キー入力の反応が大幅に改善しています。 

INPI の使い方や動作について、詳しくは上記プログラムライブラリーを参照してください。


サブルーチン:INPIメインルーチンから呼び出す直前に、4つの変数 XYDE の値を設定します。INPI はこれらの変数を参照して動作します。

 ・X: 入力ボックス開始位置の X 座標
 ・Y: 入力ボックス開始位置の Y 座標
 ・D: 入力ボックスの桁数
 ・E: インジケータの表示方法(サイズ)を設定するフラグ、0 で大きな表示、1 で小さな表示

サブルーチン:INPI は、入力確定してメインルーチンに戻る時、変数 Z に入力値を格納します。従って、INPI の直後で、変数 Z の値を、メインルーチンで使用する変数に代入しておく必要があります。

INPI を使う時は、5つの変数(XYDEZ)は、その値が変化します。つまり、これらの変数をメインルーチンで使う時は、値が変化することを前提にしてください。

0:JST の横、(X, Y) = (8, 1) の位置に、4桁の入力ボックスを表示させ、小さいインジケータ(▶E)を表示させるので、プログラムは以下のようになります。変数 J は、上でも述べたように、日本時間を格納する変数です。

8→X:1→Y:4→D:1→E
Prog "INPI"
Z→J


INPI の変数とメインルーチンの予約変数
メインルーチンでは、日本時間 J、ドイツ時間 G、ロサンゼルス時間 U、時差 P, Q など、他のサブルーチンで勝手に変更されては困る変数があります。これを予約変数と呼び、他で値が変更されても構わない変数を使い捨て変数と呼んでいます。
INPIで使う変数は当然それらの値は変更されるので、メインルーチンの予約変数には使えません。

メインルーチンの予約変数は、以下のINPIで使う変数を避けて使います。

INPI で使う変数
 C: 入力中の桁数
 D: 入力ボックスの桁数
 E: 確定ガイドフラグ
 I: for文制御変数、入力キー
 K: キーコード
 X: 入力開始桁
 Y: 入力開始行
 Z: 入力数値
 配列変数 Z[n]n = 21~23, 25, 31~33, 35~37


・時間から「時」と「分」を分離して計算する

本プログラムでは、時差の計算が最も重要な仕事です。

時差は時間単位で決まっています。そこで、日本時間 10:24 に対して、例えばドイツ時間は 2:24 であり、「分」はそのままで、「時」だけが 8 減っています。

そこで、時間から「時」と「分」を分離して、「時」を変数 A に入れ、「分」を変数 B に入れておくと、時差計算が便利になります。

時間の変数に格納される整数について、下位2桁が「分」となります。例えば日本時間 J については、以下のようにすれば「時と「分」が得られます。

Int(J÷100)→A
J-100A→B


J の値が、3桁 (0905など)、2桁(0020など)、1桁(0005など)でも、この計算が正しいことは、試してみると分かります。

ここで使っている Int( ) 関数は、( ) 内の数値の整数部分を取り出すものです。
 ⇒ Casio Basicコマンドリファレンス: Int( ) / Frac( )


・省略した入力への対応

例えば、9:00 を入力したい時、900 と 3桁を入力するよりは、9 と1桁の入力で済ませた方が楽です。6:30 を入力するには、630 と 3桁入力が楽です。

入力を省略できるのは、1桁および2桁入力の時で、入力したものを「時」として判断するようにします。そこで、入力して得られた数が2桁以下の時、つまり 100未満の数の時、その数は「時」であると判断させます。具体的には、以下のプログラムになります。

If J<100:Then
J→A:0→B

Else
Int(J÷100)→A
J-100A→B
IfEnd


これには、上記の「時」と「分」の分離計算を含みます。

但し、この計算は日本時間を入力する時だけでなく、ドイツ時間やLA間の入力時にも使いますので、サブルーチンにしておくことにします。

そこで、INPI 実行直後は、変数 Z は入力した時間になっているので、このサブルーチンでは、変数 Z で時間の値を受け取ります。サブルーチン実行後は、「時」を変数 X に、「分」を変数 Y に入れることにして、サブルーチン直後で、X→A:Y→B とすれば、メインルーチンの変数 A B に「時」」と「分」を受け渡しできます。

※ このロジックだと、例えば0時20分を入力するために 0020 と入力したり、0時5分を入力するために 0005 と入力すると、おかしなことになります。0020 と入力して [EXE] キーを押すと 2000 と表示され、0005 と入力して [EXE] キーを押すと 0500 と表示されます。0時xx分のときだけは、24xx と入力する必要があります。0時台の時間入力を例外的に 24xx と入力させるのですが、他の時間の入力の利便性を優先させることにします。

このサブルーチンのファイル名を TZC とします。計算 (Calculation) の C を使って、TZ + CTZC です。

サブルーチン:TZC のプログラム
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd



以上をまとめると、日本時間の入力処理は以下のようになります。

メインルーチンTZ:入力処理のプログラム

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
IfEnd




3.時間の計算

・入力した日本時間からドイツ時間とLA時間を得る方法

さて、今後使う予定のメインルーチンの予約変数を先に決めておきます。

 ・J: 日本時間
 ・G: ドイツ時間 (中央ヨーロッパ時間)、実はドイツ = Germany から変数を G にしました。
 ・U: LA時間 (アメリカ太平洋時間)、アメリカ = USA から変数を U にしました。
 ・A: 入力した時間を分割した「時」
 ・B: 入力した時間を分割した「分」
 ・P: 日本とドイツとの時差
 ・Q: 日本とLAとの時差

AB、P、Q  から、J、G、U を計算して、それを表示するのが、ここでの処理です。

・日本時間:
  - 「時」 = A
   但し、A が 24以上になる場合は、24 を引く (この場合は日付が変わる)
   コードは、
    A≧24⇒A-24→A
   
となる。
  - 「分」 = B
  - 時間: J = 100A + B
   コードは、
    100A+B→J
   
となる。

上記の省略入力機能では、0:05 と設定するために 0005 や 005 と入力すると 5:00 と認識され、このままだと 0:05 と設定できません。そこで、0:05 の代わりに、24:05 と設定すると、つまり 2405 と入力すれば 0:05 と認識できれば良いわけです。そこで、

A≧24⇒A-24→A

としました。

・ドイツ時間: 日本時間から時差 P (9時間) を引く
 - 「時」 = A - P (= C とおく)
  但し、A - P の結果が 0 未満になる場合は、24 を足す (この場合は日付が変わる)
  プログラムは、
   A-P→C
   C<0⇒C+24→C
  
となる。
 - 「分」 = B
 - 時間: G = 100C + B
  プログラムは、
   100C+B→G
  
となる。

・LA時間: 日本時間から時差 Q (17時間) を引く
 - 「時」 = A - Q ( = C とおく)
  但し、A - Q の結果が 0 未満になる場合は、24を足す (この場合は日付が変わる)
  プログラムは、
   A-Q→C
   C<0⇒C+24→C

  
となる。
 - 「分」 = B
 - 時間: U = 100C + B
  プログラムは、
   100C+B→U
  
となる。

日本時間が 7:00 の時、ドイツは時差8時間なので、「時」から 8 を引き算するのですが、7 - 8 = -1 となります。これは前日の 23:00 である筈なので、7 に 24 を足した上で、8 を引けば 23 が得られます。

日本時間が 7:00 の時、LAでは 前日の 14:00 ですが、7 から時差の 17 を引くと、-10 となってしまうので、上と同様にして、一旦 24 を足してから 10 を引く計算をします。

これが、C<0⇒C+24→C とした理由です。

以上のようにして、J (日本時間)、G (ドイツ時間)、U (LA時間) を計算できるようになりました。これをまとめておきます。

メインルーチン TZ:日本、ドイツ、LAの時間を計算するプログラム
If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U

Prog "TZD"
IfEnd



4.得られた時間を更新表示

時間を更新表示する部分は、何度も繰り返し使うので、サブルーチンにします。

ファイル名: TZD
表示 = Display なので、TZ + D から TZD としました。

先ずは、以下のプログラムが出発点です。

Locate 8,1,J
Locate 8,2,G
Locate 8,3,U


ここで、J は日本時間、G はドイツ時間、U はLA時間です。


時間の変数 J、G、U には、4桁だけでなく、3桁や 2桁、さらに1桁の場合もあります。一方で、大まかな方針で決めたように、表示は必要なら頭に 0 を加えて、必ず4桁の表示にします。

そこで、一旦 0000 と表示したところに、上書きして時間を表示します。

サブルーチン TZD のプログラム
Locate 8,1, "0000"
Locate 8,1,J
Locate 8,2,"0000"
Locate 8,2,G
Locate 8,3,"0000"
Locate 8,3,U



一旦、ここまでで メインルーチンTZのプログラムをまとめてみます。

メインルーチンTZ のプログラム
8→P:17→Q
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
IfEnd

Prog "TZD"

WhileEnd



これを実行してみます。

日本時間を 8:04 にするとき、804 と3桁を入力してみると、以下のような表示になりました。

36-TZ1_wrong_time  

本来は、以下の表示になるべきなので、プログラムに問題があります。

0:JST      0804
1:CET     0004
2:PST     1504
<AC>:QUIT


日本時間の変数 J には 804 が、ドイツ時間の変数 G には 4 が、LA時間の変数 U には 1504 が入っています。
従って、
 ・Locate 8,1,J 804 を8桁目から表示
 ・Locate 8,2,G4 を8桁目から表示
しているので、おかしくなります。

Locate 8,3,U
は、変数 U に入っている4桁の数 1504 を表示するので、たまたま問題ない、と言うことが分かります。

そこで Locate コマンドでは、
 ・表示する数が、1桁の場合は、11桁目から表示
 ・表示する数が、2桁の場合は、10桁目から表示
 ・表示する数が、3桁の場合は、9桁目から表示
 ・表示する数が、4桁の場合は、8桁目から表示

となるようにすれば良いことが分かります。

そこで、変数 JGU の桁数が分かれば、それぞれ

 ・Locate 12-[J の桁数],1,J
 ・Locate 12-[G の桁数],2,G
 ・
Locate 12-[U の桁数],3,U

に変更できれば、うまくゆきます。あとは、数の桁数を知る方法があれば、問題解決です。

・・・・・・・・・・

いきなり解決策を提示します。
J に入っている数の桁数は、下記の式で求められます。

1+Int(log(J))

これは、自分のプログラムで多用しており、非常に便利なものです。この式について、詳しくは以下を参考にしてください。

Casio Basic入門: Locate

fx-5800P: Locate【桁数のコントロール】


これで、Locate で正しく時間を表示できるようになりました。

Locate 8,1,"0000"
Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
Locate 11-Int(log(U)),3,U


但し、このままですと、日本時間を 0:00 にするために、0 を入力するとエラーが発生します。

実は、対数関数 log( ) を使う際の非常に重要なポイントを忘れていたからです。

対数関数 log( ) は、( ) の中の数は正の数でなければなりません。これは fx-5800P 固有の問題ではなくて、対数関数の定義です。時間は 0:00 となることがあり、日本時間の変数 J は、0:00 にするために、0 と入力すれば、0 になることがあります。日本時間が 8:00 の時は、ドイツ時間は 0:00 となり、ドイツ時間の変数 G の値は 0 になります。

幸いなことに、上の時間表示のソースでは、先ず最初に 0000 と表示してから、Locate コマンドで時間を上書きするようになっているので、時間の変数が 0 の時は、上書き表示を行わないようにすれば 0000 の表示のままで、00:00 を示します。

そこで、J が 0 でない時に時間表示を行うようにします。

例えば、Locate 11-Int(log(J)),1,J を

If J≠0:Then
Locate 11-Int(log(J)),1,J
IfEnd


とすれば良いわけです。

If 文の条件判定は、その条件が「真」なら Then 以下の処理を実行し、「真」でない( = 「偽」) ならば実行しないとなっています。

そこで、以下のようにしても良いですね。

If J:Then
Locate 11-Int(log(J)),1,J
IfEnd


「真」とは、J0 でないことで、J0 だと「偽」となります。


この3行の処理を、以下のように、スッキリと1行に記述することもできます。

J⇒Locate 11-Intlog(J)),1,J

条件ジャンプ命令 ⇒ を使っています。実は、上の If 文よりも ⇒ 命令の方が、処理速度が少し速くなります。

そこで、今回は ⇒命令を使ったコードを採用します。


If 文や ⇒命令について、詳しくは以下を参考にしてください。

Casio Basic コマンドリファレンス: If ~ then ~ IfEnd

Casio Basic コマンドリファレンス: ⇒ 命令 (条件ジャンプ)


そこで、TZD は以下のようになります。

サブルーチン TZD のプログラム
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U


では、変更した TZD の動作確認のために、TZ を起動し、[0] キーを押して日本時間として 804 と入力してみます。
以下のように、目標通りに表示することを確認できました。

37-TZ1_correct_time 


log(J) は、J が正の数の時のみ正しく計算します。J が負の数の時はエラーとなります。
上のソースでは、J が 0 でない時に Locate 11-Int(log(J)),1,J を実行するようにしました。

J⇒Locate 11-Int(log(J)),1,J

対数関数 log( ) の定義では、J>0 とすべきです。これを具体的に書けば、

If J>0:Then
Locate 11-Intlog(J)),1,J
IfEnd


とすべきです。すでに、気付いて、オカシイと思われた方もいらっしゃるでしょう。


大きなうっかりミス

INPI は、負の数を扱わない仕様なので、INPI で入力すれば必ず 0 か正の数が得られます。プログラム上 J が負になる可能性はゼロです。

上の If J>0 を使ったソースのままで、もし万一 J が負になる場合は、表示が 0000 のままになります。エラーが出ずに、間違った結果を表示することになり、このバグに気付かないかも知れません。

従って、プログラム上は、絶対に J が負にならないが、他の理由で J が負いなることがあるかどうか?
もしあれば、その原因を最初から潰す必要があります。

・・・・・・・


正直に言えば、私は当初 J が負になるケースを全く想定していませんでした。でも、何度か使っているうちに、Argument ERROR (引数エラー) が発生し、問題に気付きました。うっかりしていました。

J が負になる可能性が、1つ残っていました。

電卓で他のプログラムを走らせたり、何か計算を行っている時に、J に負の数が入る可能性があります。しかし、本プログラムが起動した直後は J の値は決まっていません。と言うのも J が初期化されていないからです。

J が 0 の時は、上記のサブルーチン:TZD で対数関数 log( ) を使う時の対処で、 問題に対処できています。
プログラムが起動する前に J に負の数が入っている可能性を取り除くには、初期化処理において J を 0 で初期化します。

0→J

を、初期化処理に追加することにします。


使う変数は、できるだけ初期化してその値を確定しておくのが安全だと、再認識しました。



ここまでで、作ったプログラムは、以下の通り:

 CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
 ※ CcLinker の紹介

メインルーチン TZ のプログラム
9→P:17→Q
0→J
Prog "TZM"

While 1

-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M

If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
IfEnd

If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Prog "TZD"
IfEnd

WhileEnd




サブルーチン:TZM のプログラム (メイン画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 1,4,"<AC>:QUIT"




サブルーチン:TZC のプログラム (時間を「時」と「分」に分離)

If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd




サブルーチン TZD のプログラム (時間の表示)
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U





今回は、日本時間を入力したら、ドイツ時間とLA時間が表示されるところまで、作りました。
次回は、ドイツ時間やLA時間を入力した時の処理も追加してゆきます。



つづく...


Casio Basic入門25 / 目次




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


 



keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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


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

Casio Basic入門23

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2015/01/19
追記: 2018/11/3


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

前回: Casio Basic入門22 - Chapter 4

[2018/11/03 追記]
 ソースコードの誤記を見直しました
 CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。


Chapter 5

◆ Chapter 5 の目標: サブルーチンを使いこなす

スマホや携帯電話には、世界の主要都市の時間を教えてくれるアプリがあります。私がスマホで使っている「世界時計アプリ」を紹介します。

SmartPhoneHomePage 

ベルリン、ロサンゼルス、日本の現在の時間が一目瞭然です。

では、ロサンゼルスの朝9時に合わせて電話したいけど、日本時間で何時になるのか?
世界時計は、その答えを教えてはくれません。

さらに、サンフランシスコ、オックスフォード(イギリス)、日本の三カ所の人が、Skypeで会議をしたいけど、全員に負担のない時間帯にするには、何時に電話会議を設定したらいいのか?
答えを知るには、苦労するのではありませんか?

これらの問題を解決するのが、今回紹介するプログラムです。


時差について

まず時差について、簡単に整理してみます。

アメリカの大陸部では、西の端と東の端では時差が3時間あり、これらの地域の間には4つのタイムゾーンがあります。これに加えてアラスカ、ハワイなどのタイムゾーンがあります。ニューヨークの朝10時はロサンゼルスでは朝7時になります。

カナダは6つのタイムゾーンがありますが、そのうち4つは、アメリカの大陸部と同じです。そこで、アメリカとカナダの大陸部をひっくるめて、北米と言うことにします。

ヨーロッパはもっと複雑で、5つ以上のタイムゾーンがあります。

さらに、北米やヨーロッパには夏時間があり、夏と冬では1時間時間が変わります。夏時間が始まる時と終わる時は、北米とヨーロッパでは異なる日時が設定され、それらは毎年異なります。従って、時差の計算は結構面倒で、うっかりすると間違えてしまいます。



世界の時間換算プログラム:TIME ZONE

私は日常的に海外とのやりとりをしているので、各国の時間を調整するのがいつも面倒でした。慣れていて頭の良い人なら、パッパッパと暗算できるのですが、見ていると計算を間違えることがよくあります。

そんなことから、日本、ヨーロッパ、北米のどれかの時間を入力したら、他の時間が連動して表示される「世界の時間換算プログラム」が欲しくなり、Casio fx-5800P の Casio Basic で作ったプログラムが、TIME ZONE です。

ほぼ毎日愛用しています。

プログラムライブラリ - TimeZone [fx-5800P]
プログラムライブラリ - TimeZone [fx-9860Gシリーズ、fx-CGシリーズ]


以下のような画面です。

34-Get Good_Time 

操作も表示も1画面内に収まっていて、ダラダラとスクロールすることもありません。これも換算プログラムの一種で、これまでに作った入力ボックス INPI を利用しますので、必要になります。
入力ボックス fx-5800P 専用


メニュー番号は、0 から 4 の5つ。これらの数字キーを普通に押してそれぞれの機能を呼び出します。さらに、これらのキーを長押しすることで、別の機能を呼び出せるように作っています。

換算プログラムは、類似の機能を積み重ねて作る傾向の高いプログラムなので、サブルーチンをうまく使うことがポイントになります。Chapter 5 では、この「世界の時間換算プログラム:TIME ZONE」をつくりながら、サブルーチンの使いこなしを紹介します。

先ずは、入力して使ってみるのも良いと思います。

TIME ZONE 操作一覧

0:JST - 
日本時間 の入力と表示
       [0] キー: 日本時間入力

1:CET - ヨーロッパ時間の入力と表示
       [1] キー:    ヨーロッパ時間入力
       [1] キー長押し: ヨーロッパ内のタイムゾーン設定
       [3] キー:    ヨーロッパの夏時間ON/OFF
       [3] キー長押し: ヨーロッパ夏時間の期間を表示
     
2:EDT
- 北米時間の入力と表示
       [2] キー:    北米時間入力
       [2] キー長押し: 北米内のタイムゾーン設定
       [4] キー:    北米の夏時間ON/OFF 
       [4] キー長押し: 北米夏時間の時間を表示



Chapter5-0
プログラムの仕様

1. 基本機能
 日本、ヨーロッパ、北米の3地域の時間を、同時に表示する。
 どれかの時間を変更すると、他の2つの時間も連動して変わる。

2. タイムゾーンの設定
 ヨーロッパと北米については、それぞれ4つのタイムゾーンから選択できる。

3. 夏時間の設定
 ヨーロッパと北米については、それぞれ夏時間かそうでないかを設定できる。

4. 夏時間の開始 / 終了日時
 ヨーロッパと北米については、夏時間の開始と終了の日時を表示する。

5. 時間入力の方法
 e-Gadget オリジナルの入力ボックス INPI を使う。



Chapter 5-1
TIME ZONE プログラムの完成形

先ずは、最終的に完成したプログラム TIME ZONE の使い方から説明します。


TIME ZONE の起動

[FILE] キーを押して、プログラムリストを表示、TIME ZONE を選びます。

1-Menu 

プログラムが起動すると、以下のような表示になります。

2-Startup 

ここで、メニュー番号 0 ~ 2 は、
0: 日本時間)
1: ヨーロッパ時間
2: 北米時間
に対応しています。

0:JST
JST は、日本標準時(Japan Standard Time)の略称です。海外では JST と呼ばれます。

1:CET
CET は、中央ヨーロッパ時間(Central Europe Time)の略称で、現地で広く使われている名称です。

2:PST
PST は、北米の太平洋標準時間(Pacific Standard Time)の略称、現地で広く使われている名称です。

メニュー番号 3 と 4 は、それぞれヨーロッパの夏時間設定、北米の夏時間設定を行います。

アルファベットと数字のみの表示で、一見よくわからないかも知れません。fx-5800P はアルファベットと数字の表示しかできませんので、しかたありません。大きさが限られた画面の中で、うまく使うために、メニュー項目には、ヨーロッパや北米でよく使われているタイムゾーンの略称を使っています。タイムゾーンは、同じ時差の地域をまとめた地域を意味します。

調べたい都市や国が、どのタイムゾーンに入るかを調べておいて、それを使うようにします。タイムゾーンについては以下で説明します。


時間の入力

[0]
 キーを押すと、日本標準時の入力ボックスが現れ、4ケタの数字を入力できます。

3-JST_inputBox 

ここで、4桁の数字 1420 を入力し、

4-JST_inputBox2 

[EXE]キーを押して入力を確定すると、ヨーロッパと北米の時間も同時に表示されます。

5-JST_input 

日本時間 14:20 は、中央ヨーロッパ時間で 6:20 、北米の太平洋時間では 21:20 だと分かります。



夏時間の設定

ここで、[3] キーを押すと、ヨーロッパ時間が夏時間になります。

6-DL_at_EU 

1:CET  0620



1:CEST 0720

に、その表示が変化します。

CET は中央ヨーロッパ標準時間で6:20だったのが、夏時間に変えると、中央ヨーロッパ夏時間の略称の CEST に変わって、時間が 7:20 に変わりました。このように、メニュー3 とメニュー4 は、それぞれヨーロッパ時間と北米時間の夏時間の設定を行います。

[3] キーと[4]キーをもう一度押すと、夏時間から標準時間へ戻ります。

ヨーロッパと北米では、夏時間の開始と終了の日時が異なるので、メニュー3 と 4 でそれぞれ別に設定します。

ところで、
ST は Standard Time の略で標準時間のことです。
DL は Daylight Saving の略で夏時間のことです。

夏時間を、よくサマータイムとも言いますが、この言葉を略すると ST となり、標準時間と区別がつきません。

ヨーロッパではサマータイムと言うことがありますが、アメリカでは デイライト・セービング と言います。そこで、夏時間をデイライトセービングの略を使って、DL として、標準時間の ST と区別することにしました。

上の写真を見ると、3:ST3:DL に変わってるのが分かり、現在は夏時間を示していることが分かります。

[3] と [4] は、押すたびに STDL が切り替わる「トグル動作」をします。

[3] をもう一度押して、標準時間に戻しました。

5-JST_input 



タイムゾーンの設定と変更

ヨーロッパのタイムゾーンのうち、TIME ZONE では、以下の4つを選んで変更できます。
- WET: 西ヨーロッパ時間、West Europe Time: イギリスやポルトガルなど
- CET: 中央ヨーロッパ時間、Central Europ Time: ドイツ、フランス、イタリアなど
- EET: 東ヨーロッパ時間、East Europe Time: フィンランド、トルコ、ウクライナ、ギリシャなど
- FET: 極東ヨーロッパ時間、Fareast Europe Time: モスクワなど


ヨーロッパのタイムゾーンは、以下のようになっています。
EU-TZ 
Time-J.net 世界時計 - 世界の時間と時差 - ヨーロッパのタイムゾーンについて から引用


イギリスのタイムゾーンを GMT と言うことが多いのですが、同じタイムゾーンにはポルトガルなども含まれますので、今回はGMTではなくて、WET (西ヨーロッパ時間、West Europe Time) という略称を使うことにしました。

モスクワ時間 (MSK UTC+3)という略称もよく使われますが、TIME ZONEでは極東ヨーロッパ時間 (FET) という略称を採用しました。モスクワ以外にもこのタイムゾーンに属する地域があるので、このようにしました。

なお、都市名で時差を設定する仕様にすると、fx-5800P の Casio Basic では、多くの主要都市名をプログラム中に書き込む必要があり、このように予め用意した都市名以外の時間を知りたい場合は、ネットなどでタイムゾーンを調べる必要があります。どうせ、タイムゾーンを調べる必要があるのならば、いきなりタイムゾーンの名称で設定しても労力は同じです。

従って、TIME ZONE プログラムでは、都市名ではなくてタイムゾーンを選択する仕様にして、汎用性を優先させました。


ヨーロッパのタイムゾーン設定を変更したい時は、[1] キーを長押し。すると以下のような「ヨーロッパのタイムゾーン設定画面」に切り替わります。

8-Select_EU_TimeZone 

現在設定されているタイムゾーンは、⇒ マークが示しています。ここで、矢印キーの左 [◀] か 右 [▶] を押して ⇒ マークを移動させます。この画面では、CET (中央ヨーロッパ標準時間) に設定されていることが分かります。

なお、夏時間に設定されているときは、ヨーロッパの各タイムゾーンの略称は、以下のような少し異なる略章で表示されます。

- WET (西ヨーロッパ標準時間) ←→ WEST (西ヨーロッパ夏時間)
- CET (中央ヨーロッパ標準時間) ←→ CEST (中央ヨーロッパ夏時間)
- EET (東ヨーロッパ標準時間) ←→ EEST (東ヨーロッパ夏時間)
- FET (極東ヨーロッパ標準時間) ←→ FEST (極東ヨーロッパ夏時間)

ヨーロッパでは夏時間をサマータイムと言って、各略称に S が加わります。


さて、タイムゾーン設定画面で、左矢印 [◀] を一回押すと、⇒マークが WET へ移動します。

9-Select_EU_TimeZone2 

ここで、右下の ▶E は、[EXE] キーを押すと、設定が確定することを示しています。

では、[EXE] キーを押して、タイムゾーンを WET で確定すると、時間表示の画面に戻ります。

10-WET 

CET (中央ヨーロッパ標準時間)では 6:20 だったものが、WET (西ヨーロッパ標準時間)では 5:20 に変化しました。CET のドイツでの 6:20 は、WET のイギリスでは 5:20 だと言うことも分かります。
この時 JST (日本)では 14:20であることは変化していません。
また、2:PDT  4:DL と表示されており、北米の太平洋夏時間では 22:20 だと示しています。

夏時間でのヨーロッパのタイムゾーン設定画面は以下のようになります。

18-TZSelect_EU_DL 

このように、タイムゾーンの設定を変える際に、夏時間であることが分かるので、勘違いを防げます。


ここで、例題です。
イギリスの朝9:30に電話で話をしたいと思えば、日本時間で何時に電話をかければ良いのか?

先ず、[1] キーを押して、入力モードに入ります。

11-inputWET  

4桁の「入力ボックス」が表示されたので、ここで 930 と3桁だけ入力します。

12-inputWET2 

これで、[EXE] キーを押して確定すると、

13-WET930 

1:WET の右には、0930 と表示されました。4桁すべてを入力せず、3桁入力も受け付けるようにしています。

日本時間 0:JST のところは、1830 と変わりました。日本の夕方の6:30に電話すれば、イギリスの朝 9:30 に話が出来ることが簡単に分かります。

入力の省略機能ですが、次のようなこともできます。

[1] キーを押して、ヨーロッパ時間を入力モードにし、2桁の 10 とだけ入力します。

14-WET1000input 

そして [EXE] キーで確定すると、以下の画面のように 1:WET  1000 と表示されます。

15-WET1000input3 

入力時に省略したものは 0 と判断しています。

では、9:00 を入力するのに、1桁の 9 とだけ入力しても、0900 と判断される筈です。

16-WET900input 

このように、4桁の入力ボックスに、1桁の 9 を入力して、[EXE] キーで確定すると、

17-WET900input2 

1:WET のところは、0900 となります。

このような入力の省略機能は、数行のプログラムコードで、とても簡単に実現できます。


次に、北米のタイムゾーンについて説明します。

北米には、アメリカとカナダでは、それぞれ異なるタイムゾーンがありますが、大陸部は共通した4つのタイムゾーンがあり、プログラム TIME ZONE では、以下の共通した4つのタイムゾーンを設定できるようにしています。

- PST: 太平洋標準時間(Pacific Time): シアトル、サンフランシスコ、ロサンゼルスなど
- MST: 山岳部標準時間(Mountain Time): ソルトレイクシティー、デンバーなど
- CST: 中部標準時間(Central Time): シカゴ、ダラス、ヒューストンなど
- EST: 東部標準時間(Eastern Time): ボストン、ニューヨーク、マイアミなど

プログラム起動時はPSTになっています。おおよそロッキー山脈より西側、例えばサンフランシスコはPST(太平洋時間)です。ロッキー山脈やそれより東側のふもと、例えばコロラド州などはMST(山岳部時間)です。それより東のシカゴやテキサスなどはCST(中部時間)です。一番東の大西洋側、例えばニューヨークやフィラデルフィアなどはEST(東部時間)です。

北米のタイムゾーンは以下のようになっています。

US-TZ 
Time-J.net 世界時計 - 世界の時間と時差 - アメリカの時差と現在時刻 から引用

おおよそ南北の境界線で、4つのタイムゾーンに分けられていますので、ヨーロッパよりは分かりやすいと思います。


[2] キーを長押しすると、北米のタイムゾーン設定画面に切り替わります。

TZSelect_NA 

今は、⇒ マークが PST についており、太平洋標準時間に設定されていることが分かります。

矢印キー [◀][▶] を使って、⇒ マークを他のタイムゾーンに移動させ、[EXE] キーで確定します。

以下の画面では、2:PDT   4:DL と表示されており、北米は太平洋夏時間に設定されていることが分かります。

20-DL_NA 

ここで、[4] キーを使って、北米の標準時間と夏時間を切り替えることもできます。


同じ英語でもヨーロッパと北米では夏時間の言い方が変わるようで、北米では夏時間をサマータイムとは呼ばず、デーライトセービングタイム(Daylight Saving Time)と言い、各タイムゾーンの夏時間の略称は SD に置き換えて以下のように呼ばれます。

- PST (太平洋標準時間) ←→ PDT (太平洋夏時間)
- MST (山岳部標準時間) ←→ MDT (山岳夏時間)
- CST (中部標準時間) ←→ CDT (中部夏時間)
- EST (東部標準時間) ←→ EDT (東部夏時間)



夏時間開始と終了の日時を調べる

[3] キーか [4] キーのいずれかを長押しすると、以下の画面が表示され、ヨーロッパと北米の夏時間の開始と終了の日時が分かります。

27-TZInfo 

この表示内容は、プログラム中に書き込んであります。夏時間開始と終了の日時は毎年変わりますので、新しい年の開始と終了日時が分かれば、プログラムを変更して、表示内容を更新しておきます。



使い方の例

課 題
明日は2014年10月30日。モントリオールに出張中の担当者と、日本の居る私、そしてドイツのメンバーとで電話会議を行いたい。出張者は午前中に訪問先との約束があるので、早朝が良い。そこで、明日の2014年10月30日にモントリオール、ドイツ、日本のそれぞれの参加者の都合が良く、無理のない電話会議開始時間を決めたい。


まず、TIME ZONE を起動します。

2-Startup 


さて、2014年10月30日では、ヨーロッパと北米の夏時間がどうなっているのか、最初に知る必要があります。

上で紹介した Time-J.net などを利用して調べても良いのですが、それも面倒なので TIME ZONE には、夏時間の開始と終了の日時を表示する機能を持たせています。[3] キーか [4] キーを長押しすると、この情報を表示します。

27-TZInfo 

これを見ると、2014年10月30日時点で、ヨーロッパでは夏時間が終わって標準時間になっており、北米ではまだ夏時間です。

そこで、[4] キーで北米を夏時間にします。

28-Set_NA_DL   


2:PDT と表示されているので、太平洋夏時間です。モントリオールは東部時間のタイムゾーンにあるので、東部時間に切り替えます。

[2] キーを長押し、

21-TZSelect_NA_DL 

矢印キーで、東部発時間の EDT を選びます。

左矢印 [◀] キーを一回押すだけで、⇒ マークは右下へ移動します。

左矢印 [◀] キーを、ポン、ポン と叩き続けると、⇒ マークは、グルグルと巡回するようになっています。


⇒ マークを EDT に合わせた後、

22-TZSelect_NA_DL2 

[EXE] キーで確定すると、

29-Set_NA_EDT  

このように、タイムゾーンと夏時間の設定が終わりました。

なお、ヨーロッパは、1:CET、2:ST となっているので中央ヨーロッパ標準時、つまり2014年10月30日のドイツ
 の設定になっているので、ここは変更する必要はありません。

ここで、モントリオール時間を試しに、6:00 とします。
そこで、[2] キーを押して、入力ボックスさせ、

30-Input_NA_EDT  

6 と入力し、

31-Input_NA_EDT2 
  
[EXE] キーで確定すると、

32-Set_NA_EDT_at_600 
 
モントリオールの時間とともに、日本とドイツの時間も表示されました。

日本とヨーロッパの人は、この時間で良いのですが、モントリオールの人は、チョット朝が早すぎるようです。

そこで、6:30 に変更してみましょう。

[2] キーを押して、入力ボックスに 630 と入力し、

Change_NA_EDT_to_630 

[EXE] キーで確定すると、

34-Get Good_Time 

日本は19:30、ドイツは11:30、モントリオールは6:30なので、これで電話会議開始時間としましょう....

...といった使い方になります。


Chapter 5 では、このような「世界時間表示プログラム TIME ZONE」 を紹介してゆきます。




つづく...



Casio Basic入門24 / 目次




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


 



keywords: fx-5800PCasioBasic、世界時間換算, プログラミング入門プログラム関数電卓

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


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

Casio Basic入門58

Casio Basic入門
<目次>

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

 2017/11/04
追記 2017/11/05
修正 2017/11/11


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

Chapter 10 - 中級

◆ Chapter 10 の目標: 3桁区切り出力 - 汎用サブルーチンの作成

前回: Casio Basic入門57 を見る


これまでに、fx-5800P版3桁区切りサブルーチン (下記) が完成しました。

前回完成させた "高速3桁区切り出力・汎用サブルーチン" fx-5800P版:3DS
Z=0⇒Return

Int(log(Z))+1→K
(K≥4)+(K≥7)+(K≥10)→I

X→D:X→W
X=0⇒17-K-I→X
If X+K+I>17 Or K≥13
Then
X+K≥17⇒17-K→D
If K≥11:Then
2→D:X<2⇒X→D
W=0⇒2→D
IfEnd
Locate D,Y,Z
Return:IfEnd

X103Frac(Z÷X103)→U
Int(X103Frac(Z÷X106))→V
Int(X103Frac(Z÷X109))→W
Int(Z÷X109)→D

If K≤8:Then
Locate X,Y,X108W+X104V+U
I≥1⇒Locate X+K-2-(I=1),Y,","
I≥2⇒Locate X+K-6,Y,","
Else
X+K-6+(I≥3)→J
Locate J,Y,X107+X104V+U
Locate X,Y,X104D+W
Locate J+4,Y,","
Locate J,Y,","
I≥3⇒Locate X+K-9,Y,","
IfEnd


今回は、3DS の使いこなし例を紹介します。


Chapter 10-4
3桁区切りサブルーチン fx-5800P版 の使いこなし

3桁区切りサブルーチン 3DS は、手軽に使ってこそ価値があると思います。そこで、旧来の命令を使った手軽なプログラムで使いこなす例を紹介します。


指定位置に3桁区切り出力

かけ算プログラム:3DS TEST
"A"?→A
"B"?→B
"C"?→C
"A×B×C="
7→X:4→Y:ABC→Z
Prog "3DS"


これは、変数 ABC に値を入力させ、A×B×C を計算した結果を出力するプログラムです。

実行すると、

 A?

と表示されるので、例えば 12 と入力すると、A12 が格納され、

 A?
 12
 B?


と表示されます。次に 45 と入力すると、B45 が格納され、

 12
 B?
 45
 C?


と表示されます。最後に 78 と入力すると、C78 が格納され、さらに ABC の計算結果を表示します。

 45
 C?
 78
 A×B×C=42,120


4行目に A×B×C= に続いて3桁区切りで出力されています。

旧来の出力命令 " " が実行されると自動的に改行されるので、入力行が1行づつ下に下がります。改行が4行目に達すると、入力行は4行目に固定され、画面表示が1行上にスクロールされる、これが Casio Basic の仕様です。

従って、上のプログラムでは、A×B×C の計算結果が4行目に出力されることを理解していれば、Prog "3DS" の直前の設定で 4→Y で良いことが分かります。 A×B×C= に続いて計算結果を出力させるために、7→X と設定しています。


右寄せで3桁区切り出力

上のプログラムの最後に(一旦停止)を追加し、さらに3行追加しました。

かけ算プログラム:3DS TEST
"A"?→A
"B"?→B
"C"?→C
"A×B×C="
7→X:4→Y:ABC→Z
Prog "3DS"

"A×B×C="
0→X:4→Y:ABC→Z
Prog "3DS"


追加分は、右寄せで3桁区切り出力させるために 0→X と設定しています。

実行して、A=12、B=45、C=78 を入力し、以下の画面まで進みます。

 45
 C?
 78
 A×B×C=42,120


命令で一旦停止しているので、[EXE] で次に進むと、

 C?
 78
 A×B×C=42,120
 A×B×C=   42.120


と表示されます。乗算結果 ABC が右寄せで3桁区切り出力されています。


大きな桁の出力

上で最後に作ったプログラムに下記のような追加(赤文字で示す)を行います。

"A"?→A
"B"?→B
"C"?→C
"AxBxC="
7→X:4→Y:ABC→Z
Prog "3DS"

"AxBxC="
0→X:4→Y:ABC→Z
Prog "3DS"


"AxBxC="
" "
0→X:4→Y:ABC→Z
Prog "3DS"


そして、A=1234、B=4567、C=7891 を入力してみると、画面は先ず

 4567
 C?
 7891
 A4.44711351
X1010


となり、一旦停止を解除するために [EXE] を押すと

 C?
 7891
 A4.4411351
X1010   
← 指数表示が右寄せになっている
 A×44,471,135,098  
← 3桁区切り出力が右寄せになっている


となります。3DS の仕様により出力が右に溢れないように、左にずらして出力されており、仕様通りです。但し出力結果は見づらいものです。

さらに [EXE] を押すと、

 A4.44711351X1010
 A×44,471,135,098

 A×B×C=
    44,471,135,098


と、改行&右寄せが適していることが分かります。

0→X と設定した時に右寄せ出力する機能を追加したのは、このような出力が有効だと考えたからです。


大きな桁の出力を試すプログラム

上記のプログラムの最後にコードをさらに追加して、もっと大きな桁で出力するサンプルプログラムを作ってみます。

ちなみに上のプログラムでは、実行を一旦停止するために 旧来の命令 を使い、文字列出力のために " " 命令(出力文字無し)を使っています。この場合 " " は内部カーソル行を改行し、その次に実行される出力命令 " " は改行された位置に出力します。ところが内部カーソル行が4行目になると、内部カーソル行は常に4行目になるので、" "  命令での出力位置は常に4行目となります。

内部カーソル行が4行目になっているときに 4→Y: Prog "3DS" を実行すると、4行目の表示の上に3桁区切り出力が上書きされます。上書きせず改行して出力したい時は、画面を1行上にスクロールさせるために " " 命令 (出力文字なしで改行のみ)を利用しています。

これは、Casio Basic の旧来の命令 " "Locate コマンドを併用する時のチョットしたコツです。

3DS TEST Src for fx-5800P 

これを実行し、A=123、B=345、C=7891 を入力すると、

 456
 C?
 7891
 A×B×C=442590408


[EXE] を押すと、

 C?
 7891
 A×B×C=442590408
 A×B×C442,590,408


[EXE] を押すと、

 A×B×C=442590408
 A×B×C442,590,408
 A×B×C=
     442,590,408


さらに [EXE] を押すと、Cls で画面消去し、

 A×B×C=
     442,590,408


さらに [EXE] を押せば、

 A×B×C=
     442,590,408
 4×A×B×C=
    1,770,361,632




さらに、[EXE] を押して、

 4×A×B×C=
   1,770,361,632
 16×A×B×C=
   7,081,446,528


最後にもう一度 [EXE] を押すと、

 16×A×B×C=
    7,081,446,528
 256×A×B×C=

  113,303,144,447

と表示されます。改行して右寄せで出力すると、大きな桁が見やすくなると思います。

色々と試してみてください。


入力ボックスINPIと3桁区切り3DS の組み合わせ - 3DS DEBUG2 [2017/11/05 追記]
前回 Casio Basic入門57 (Chapter 10-3) で、デバッグ用プログラム 3DS DEBUG2 を紹介していますが、これは入力ボックス INPI と 3桁区切り 3DS を組み合わせて使っています。

INPI3DS は共に 出力位置 (X, Y) と入出力値 Z の意味で、変数 X, Y, Z をサブルーチンに渡す仕様なので、X, Y Z をうまく共有して使えます。改めてプログラムソースを紹介します。

3DS DEBUG2 Src for fx-5800P 


入力ボックスと3桁区切り3DS の組み合わせ - COMPINT [2017/11/11 修正]
Casio Basic入門51 (複利計算プログラム) で入力ボックスの使いこなしを紹介し、さらに3桁区切りサブルーチンを作り組み合わせました。今回の汎用サブルーチン 3DS の原点となったプログラムです。

そこで、[最終版] 複利計算プログラム (3桁区切り) のプログラムを示します。
入力ボックス2INPI 2.0INP 2.1 を利用します。

CompInt src for fx-5800P 




fx-5800P版 高速3桁区切り出力・汎用サブルーチン - 3DS

完成した fx-5800P 版 3桁区切り・汎用サブルーチンを改めて示します。

※ ダウンロード: 3DS for fx-5800P ソースファイル (pdfファイル)

3DS_src_fx5800P.jpg 




次回は、3DS を fx-9860GII と fx-CG50 に移植します。


つづく...

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



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


 



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

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



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

Casio Basic入門 -目次-

Casio Basic入門

新しい記事の公開に合わせて随時追記・修正します
最終: 2017/11/10


目 次

        - 1.はじめに: [1]

        - 2.プログラミングとは: [1]  

        - 3.fx-5800PのCasio Basicコマンド一覧: [2] 

        - 4.Casio Basicを使ってみる
            - Chapter 0 - プログラム作成・実行のポイント: [2] 
            - Chapter 1 - Getkey と Locate を使いこなす: [3] [4] [5] [6] [7] [8] 
            - Chapter 2 - 動きのあるプログラムを作る: [9] [10][11][12][13][14] 
            - Chapter 3 - 自由自在に入力する(入力ボックス): [15][16][17][18] 
            - Chapter 4 - 換算プログラムを作る: [19][20][21][22] 
            - Chapter 5 - サブルーチンを使いこなす: [23] [24] [25] [26] [27] [28] [29] [30] [31] 
            - Chapter 6 - プログラムを速くする(入力ボックス) [32] [33] [34] [35] [36] [37]  
            - Chapter 7 - 超入門 - ゼロからのプログラム作成と機能追加: [38] [39] [40] [41] [42]
            - Chapter 8 - Basic 命令を活用してみる: [43] [44] [45] [46] [47] [48] [49] [50]
            - Chapter 9 - 簡単な換算プログラム - 入力ボックスの活用: [51] [52] [53] [54] 
            - Chapter 10 - 3桁区切り出力 - 汎用サブルーチンの作成: [55] [56] [57] [58] [59]  
            - Chapter 11 - 


        - 5.Casio Basicでグラフィックス / 目次
            - Chapter G01 - LCDと3つの座標系: [G01] 
            - Chapter G02 - グラフィックス画面の設定と描画: [G02] 
            - Chapter G03 - ClrGraphViewWindow[G03] 
            - Chapter G04 - Plot コマンド: [G04] 
            - Chapter G05 - Plot と ViewWindow: [G05] 
            - Chapter G06 - F-Line と線のスタイル設定: [G06] 
            - Chapter G07 - 点線とViewWindow: [G07]
            - Chapter G08 - ViewWindow の有効活用 / RclPict と RclCapt の違い: [G08] 
            - Chapter G09 - ViewWindow と設定変数: [G09] 
            - Chapter G10 - Circle コマンド: [G10] 
            - Chapter G11 - PxlOn コマンド: [G11]
            - Chapter G12 - PxlOff コマンド: [G12]
            - Chapter G13 - PxlChgコマンド: [G13] 
            - Chapter G14 - PxlTest( ) コマンド: [G14] 

            - Chapter G15 - 
            - Chapter G16 - 
            - Chapter G17 -
            - Chapter G18 -

詳細な目次へ



Casio Basic入門の概要

CasioBasic入門では、最初から順に読むことを前提に書き始めました。最初は基本的な部分から丁寧な説明を心がけていますが、進むにつれて同じ説明を省略するようになります。Casio Basicの命令やコマンドの使い方だけでなく、プログラミングの考え方、手法、知っておくと役立つ話題なども、折に触れ紹介しています。

当初、fx-5800P 使用を前提にして始めていますが、「4. Casio Basic を使ってみる」 で取り上げているプログラムは、簡単な変更で fx-9860GII や fx-CG50 への移植も可能です。具体的に fx-9860GII や fx-CG50 などへの移植を取り上げた記事もあります。

fx-CG20 / CG50 については、fx-9860GII の Casio Basic プログラムからの移植性が非常に高く、物理座標系で動くグラフィックスコマンド(TextPxlOnPxlOffPxlChgPxlTest) を使っていないプログラムは、fx-CG20 / CG50 に転送するだけで、ほぼ正常動作します。

Casio Basic - 機種別の互換性

fx-9860GII への移植 - 厄介な旧来の命令


「5. Casio Basic でグラフィックス」 は、グラフィックス機能を持たない fx-5800P ではなく、fx-9860GII を前提にしています。ここで紹介しているプログラムは fx-CG-20 / fx-CG50 で動作します。というのも、fx-CG20 / fx-CG50 は、カラー対応の部分を除き、fx-9860GII の上位互換になっているからです。fx-9860GII からの互換性の無いコマンドは僅かですが、fx-CG20 / CG50 で互換性のないコマンドについては、順次追加する予定です。


Casio Basic入門の読み方

PCなどでの構造化Basic や他の構造化高級言語でのプログラミング経験者には、最初から順に読み進めて頂ければ、Casio Basic が構造化プログラミング可能で、意外に使えることに気付かれると思います。

昔の古い電卓やポケコンでの行番号付きのBASICでのプログラミング経験しか無い方、およびプログラミング未経験者の方は、以下の順序で読み進めると良いと思います。

構造化高級言語によるプログラミング経験の少ない方、プログラミング初心者向けの進め方

2. プログラミングとは
   
4. Casio Basicを使ってみる [fx-5800P 向け。fx-9860GII や fx-CG20 / CG50 にも移植可能]
   
 ・Chapter 0 (プログラム作成・実行のポイント)
   
 ・Chapter 7 (超入門:ゼロからのプログラム作成と機能追加) ※1
   
 ・Chapter 8 (Basic コマンドを使ってみる) ※2
   
 ・Chapter 1 (Getkey と Locate コマンドを使いこなす)
   
 ・Chapter 2 (動きのあるプログラムを作る)
   
 ・Chapter 3 ~ Chapter 6 / Chapter 9 ~
   
5. Casio Basic でグラフィックス [fx-9860GII 他、グラフ関数電卓向け]

※1 fx-5800P プログラミング(超)入門
Chapter 7 (超入門:ゼロからのプログラム作成と機能追加) は、fx-5800P を始めて使うプログラミング未経験者を想定したものです。Chapter 8 へ繋がります。 ⇒ Chapter 7

※2 新世代 Casio Basic への導入
Chapter 8 は、カシオのプログラム電卓で古くから使われてきた命令から、新世代 Casio Basic への導入を目的にしています。古いプログラム電卓を使いこなしているが、新しい Casio Basic にはなじみの無い方向けです。 ⇒ Chapter 8

※3 PCなどでの高級言語プログラミングの経験者には...
管理人自身がこのカテゴリーに入ります。高級言語、特に構造化Basicでのプログラミング経験者は、当ブログで公開している Hit & Blow ( ここここ や ここ )、もぐら叩き (ここ) を見て、実際に fx-5800P で実行して頂ければ、Casio Basic の能力が分かると思います。さらに、改造や改善してみると Casio Basic がさらに分かると思います。

記事中で、Casio Basic コマンドリファレンスの個別項目へのリンクも入れています。このコマンドリファレンスは、管理人オリジナルのもので、取扱説明書に書かれていない多くの情報を提供しています。


新世代 Casio Basicについて

2006年発売の fx-5800P に搭載されたプログラミング言語は、カシオ自身が Basic-Like プログラミング言語と言っています。機能やコマンドが限定されているので、厳密にはその通りです。しかし実際に使ってみると、使えるコマンドに着目すれば、構造化プログラミングができる Basic であり、実用的な電卓プログラムが作れることに気がつきました。構造化プログラミングには諸説ありますが、当ブログでは Knuthが提案した「ブロック構造による分かりやすいプログラムを作ること」 が構造化プログラミングだ、との立場です。例外処理やエラー処理のために Goto で処理を一カ所に集中させるのは、プログラムが分かりやすくなるので良いものとして考え、それ以外は極力 Goto なしでプログラムを書くという考え方です。実際に多くの高級言語では、例外処理には内部的に Goto と同様に特定アドレスへの強制ジャンプをしています。

ここでは、カシオ製 プログラム関数電卓とグラフ関数電卓をひとくくりにして、プログラム電卓と呼ぶことにします。2006年に 発売された fx-5800P 以降のプログラム電卓に搭載されている Casio Basic は、構造化プログラミングが可能である点で、それ以前のものとは大きく異なります。

そこで、fx-5800P 以降の機種に搭載されている新しい Casio Basic を 当ブログでは、新世代 Casio Basic と呼んでいます。これらに共有しているのは、構造化プログラミングが可能で、テンキーだけでなく全てのキー([AC]キー除く)押下の検出が可能な Getkey コマンド、そして柔軟な Locate コマンドを搭載し、条件判定を 0で偽、0以外を真 (論理演算は 1 で真) となることです。これは一般的な高級言語と同じです。なお、プログラム関数電卓として販売されている fx-71F や fx-72F に搭載されている言語は、ここでいう新世代 Casio Basic ではありません。

<新世代Casio Basic搭載機>
  - fx-5800P
  - fx-9860G (OS ver 2.以降推奨)
  - fx-9860GII (OS ver 2 以降推奨)
  - fx-CG10
  - fx-CG20
  - fx-FD10 Pro
  - fx-CG50
  ※ OS は最新バージョンへアップグレードできます

初級・中級の表記について
  初級 - Casio Basic の命令/コマンドの使い方を覚えるレベル
  中級 - プログラムの構造やロジック、変数の使い方を工夫するレベル
  中級者で十分使いこなせるので、上級と言う表記はありません

Casio Basic でのグラフィックス プログラミングを取り上げています。先ずは グラフィックスコマンドを徹底的に調べている段階なので、別系統で連載します。これまでの「Casio Basicを使ってみる」の連載は、継続予定です。
 ⇒ Casio Basicでグラフィックス


詳細な目次

1. はじめに
      ⇒ Casio Basic入門1

2. プログラミングとは
      ⇒ Casio Basic入門1

3. fx-5800P CasioBasicのコマンド一覧
      ⇒ Casio Basic入門2

4. CasioBasicを使ってみる
[fx-5800P 向け] (fx-9860GII、fx-CG20、fx-CG50にも移植可)

Chapter 0

プログラム作成・実行の操作ポイント

      - プログラム新規作成
      - プログラム編集
      - プログラム実行
      - →命令 (代入命令)
      - ?命令 (入力命令)
      - 命令 (出力命令)

      ⇒ Casio Basic入門2

Chapter 1 - 初級
Getkey と Locate コマンドを使いこなす
キーコード取得プログラム - GET KEYCODE を作る 

      - Locate
      - Getkey
      - Doループ
      - Whileループ
      - Isz命令 (インクリメント・ジャンプ命令)
      - " " 出力命令
      - EngOn / EngOff
      - If 文
      - ⇒命令 (条件ジャンプ命令)


      ⇒ Casio Basic入門3
             - Chapter 1-1: Getkey、Locate
             - Chapter 1-2: Goto / Lbl ループ、EngモードとLocate

      Casio Basic入門4
             - Chapter 1-3: 繰り返し処理 Doループ

     Casio Basic入門5
             - Chapter 1-4: Locateコマンドと出力命令" "の違い
             - 
Chapter 1-5: 思い込みの罠 - Locateの表示桁数
             - Chapter 1-6: プログラム完成
             - Chapter 1-7: 思い込みの罠(補足) - 1桁のキーコード

      ⇒ Casio Basic入門6
             - Chapter 1-8: DoループとWhileループ再び

      Casio Basic入門7
             - Chapter 1-9: Locateコマンドで陥るバグ
             - Chapter 1-10: 利用価値の高い⇒命令(条件ジャンプ)を使ってみる

      ⇒ Casio Basic入門8
             - Chapter 1-11: ダイナミックな表示機能の実装
             - Chapter 1-12: プログラムのバックアップ


Chapter 2 - 初級
動きのあるプログラムを作る
反射ゲーム - REACT を作る

      - Lbl / Goto ループ
      - Dsz命令 (ディクリメント・ジャンプ命令)
      - Int( ) / Frac( ) 関数
      - Break コマンド
      - 例外処理 / 例外フラグ
      - 複数条件分岐 - Else If
      - ブロック構造 (構造化プログラミングの勧め)
      - アルファベット小文字の表示
      - For~To~Next
      - Progコマンド(サブルーチン)

      ⇒ Casio Basic入門9
             - Chapter 2-0: Lbl / Gotoループを使う
             - Chapter 2-1: 回る羽根を作る

      ⇒ Casio Basic入門10
             - Chapter 2-2: ランダム関数を使う
             - Chapter 2-3: 再びGetkeyとDoループでカウンタ計測
             - Chapter 2-4: 例外処理・例外フラグ・Breakコマンド

      ⇒ Casio Basic入門11
             - Chapter 2-5: プログラム制御
             - Chapter 2-6: 複数条件分岐の記法

      ⇒ Casio Basic入門12
             - Chapter 2-7: ゲーム終了条件の実装

      ⇒ Casio Basic入門13
             - Chapter 2-8: ゲーム進行に変化を付ける
             - Chapter 2-9: ゲームの仕上げ - 構造化プログラミング

      ⇒ Casip Basic入門14
              - Chapter 2-10: For文とProgコマンドを使ってみる


Chapter 3 - 中級
自由自在に入力する
入力ボックス - INPI を作る

      - 配列変数
      - 論理演算コマンド
      - For~To~Next
      - Progコマンド(サブルーチン)
      - サブルーチンの使い方
      - アルファベット小文字の表示
      - デバッグ方法
      - ド・モルガンの法則
      - 変数の使い方 - 予約変数と使捨て変数
      - 変数の適用範囲

      ⇒ Casio Basic入門15
             - Chapter 3-0: 動作確認用メインルーチンを作る

      ⇒ Casio Basic入門16
             - Chapter 3-0(続き): 「入力ボックス」を作る - 論理演算をする

      ⇒ Casio Basic入門17
             - Chapter 3-1: 「入力ボックス」プログラムの改造

      ⇒ Casio Basic入門18
             - Chapter 3-2: 入力ボックス - 末尾文字の削除機能を追加する
                デバッグ方法、ド・モルガンの法則、変数の適用範囲を理解する


Chapter 4 - 中級
換算プログラムを作る
和暦・西暦変換プログラム - YEAR CONV を作る

      - Progコマンド (サブルーチン)
      - サブルーチンの使い方
      - 変数の使い方 - 予約変数と使い捨て変数

      ⇒ Casio Basic入門19
             - Chapter 4-0: 和暦・西暦換算プログラム - 完成状態の紹介
             - Chapter 4-1: 最初にプログラム構造を考える
             - Chapter 4-2: 和暦・西暦換算プログラムを実装する

      ⇒ Casio Basic入門20
             - Chapter 4-3: オマケ機能の追加 - 数の桁数の求め方

      ⇒ Casio Basic入門21
             - Chapter 4-4: キー長押しによるメニュー選択

      ⇒ Casio Basic入門22
             - Chapter 4-5: キー長押しの処理を作る
             - Chapter 4-6: サブルーチンを使いこなす


Chapter 5 - 中級
サブルーチンを使いこなす

世界時間換算プログラム - TIME ZONE を作る

      - 入力ボックスを使う
      - サブルーチンを活用した効率的な機能追加
      - 変数の使い方 - 予約変数と使捨て変数
      - キー長押しの活用
      - 矢印キーによる循環項目選択

      ⇒ Casio Basic入門23
            - Chapter 5-0: プログラムの仕様
            - Chapter 5-1: TIME ZONE プッログラムの完成形

      ⇒ Casio Basic入門24
            - Chapter 5-2 Getkey、入力ボックス、Locate の活用

      ⇒ Casio Basic入門25
            - Chapter 5-3: 同様の機能を追加する

      ⇒ Casio basic入門26
            - Chapter 5-4: 少し異なるルーチンを、分かりやすく追加する

      ⇒ Casio Basic入門27
            - Chapter 5-5: 少し異なるルーチンを、分かりやすく追加する(2)

      ⇒ Casio Basic入門28
            - Chapter 5-6: キー長押しによる機能呼び出し

      ⇒ Casio Basic入門29
            - Chapter 5-7: 矢印キーの活用

      ⇒ Casio Basic入門30
     - Chapter 5-8: 類似処理による機能追加

      ⇒ Casio Basic入門31
     - Chapter 5-9 キー長押しによる別機能の呼び出し


Chapter 6 - 中級
プログラムを速くする
入力ボックスの高速化と拡張 - 入力ボックス 2.0 を作る

      - 処理速度の遅いコマンド/命令を見極める
      - プログラムロジックの見直し

      ⇒ Casio Basic入門32
     - Chapter 6-0: コマンドや命令の処理速度を比較する
     - Chapter 6-1: 具体的に対処する遅い処理を見つける

      ⇒ Casio Basic入門33
     - Chapter 6-2: ロジックの見直しでプログラムを高速化する

  ⇒ Casio Basic入門34
     - Chapter 6-3: 処理速度を意識して機能拡張する

  ⇒ Casio Basic入門35
     - Chapter 6-4: 処理速度を意識して機能拡張する

  ⇒ Casio Basic入門36
     - Chapter 6-5: キーリピートを抑制する

  ⇒ Casio Basic入門37
     - Chapter 6-6: fx-5800P から fx-9860GII へ移植する


Chapter 7 - 超初級
ゼロからのプログラム作成と機能追加
温度換算プログラム- TEMP CONV を作る

      - 初めての fx-5800P プログラミング
      - プログラム作成の手順
      - プログラムの実行方法
      - ?(入力)命令

  ⇒ Casio Basic入門38
     - Chapter 7-1: 最もシンプルなプログラム

  ⇒ Casio Basic入門39
     - Chapter 7-2: 同様の機能を追加する

  ⇒ Casio Basic入門40
     - Chapter 7-3: 選択肢3つの換算プログラムに拡張する

  ⇒ Casio Basic入門41
     - Chapter 7-4: バグの原因と対処 - フラグの利用

  ⇒ Casio Basic入門42    
     - Chapter 7-5: プログラムの効率化


Chapter 8 - 初級
Basic 命令を使ってみる
温度換算プログラム - TEMP CONV を作る

   - ?(入力)命令を Baisc コマンでに置き換える
     ・ Getkey と Do ループ の使い方
     ・ 入力ボックスの使い方
   - ⇒(条件分岐)命令のメリット
   - キー入力制御
     ・ Getkey と While ループの使い方

  ⇒ Casio Basic入門43
     - Chapter 8-1: メニュー選択に Getkey を使う

  ⇒ Casio Basic入門44
     - Chapter 8-2: 入力ボックスを使ってみる

  ⇒ Casio Basic入門45
     - Chapter 8-3: 換算プログラムの入力ボックスを実装する

  ⇒ Casio Basic入門46
     - Chapter 8-4: テンキー以外のキー入力を利用する

  ⇒ Casio Basic入門47
     - Chapter 8-5: [EXIT] キーで正常終了させる

  ⇒ Casio Basic入門48
     - Chapter 8-6: グラフ関数電卓用入力ボックスを準備する

  ⇒ Casio Basic入門49
     - Chapter 8-7: グラフ関数電卓へプログラムを移植する

  ⇒ Casio Basic入門50
     - Chapter 8-8: グラフ関数電卓用に表示を最適化する


Chapter 9 - 初級
簡単な換算プログラム - 入力ボックスの活用
福利計算プログラム - CompInt を作る

   - Getkey と Do ループ の使い方
   - 入力ボックスの使い方
   - 数値の3桁区切り表示をサブルーチンで実装
   - 3桁区切りのロジックを改善(高速化)

  ⇒ Casio Basic入門51
     - Chapter 9-1: fx-5800P で複利計算プログラムを作る

  ⇒ Casio Basic入門52
     - Chapter 9-2: fx-5800P で3桁区切り表示をする

  ⇒ Casio Basic入門53
     - Chapter 9-3: fx-5800P での3桁区切り表示を高速化する

  ⇒ Casio Basic入門54
     - Chapter 9-4: fx-5800P での3桁区切り表示を改良する


Chapter 10 - 中級
3桁区切り出力 - 汎用サブルーチンの作成と活用
3桁区切り出力・汎用サブルーチン - 3DS を作る

   - 数値の3桁区切り出力を汎用サブルーチン化
   - 旧来の出力命令 " " 、出力命令 の癖
   - 大域変数の使いこなし

  ⇒ Casio Basic入門55
     - Chapter 10-1: 高速3桁区切り出力サブルーチンの特長

  ⇒ Casio Basic入門56
     - Chapter 10-2: 高速3桁区切り出力サブルーチンの評価と改善

  ⇒ Casio Basic入門57
     - Chapter 10-3: 3桁区切りサブルーチン fx-5800P版 右寄せ出力機能の追加

  ⇒ Casio Basic入門58
     - Chapter 10-4: 3桁区切りサブルーチン fx-5800P版の使いこなし

  ⇒ Casio Basic入門59
     - Chapter 10-5: 3桁区切りサブルーチン グラフ関数電卓版


5. Casio Basicでグラフィックス [fx-9860GII / fx-CGシリーズ向け]

Casio Basicでグラフィックス
グラフィックスコマンドの仕様や特徴

  ⇒ Casio Basic入門G01
     - Chapter G01: LCDと3つの座標系

  ⇒ Casio Basic入門G02
     - Chapter G02:  グラフィックス画面の設定と描画

  ⇒ Casio Basic入門G03
     - Chapter G03: ClrGraphViewWindow

  ⇒ Casio Basic入門G04
     - Chapter G04: Plot コマンド

  ⇒ Casio Basic入門G05
     - Chapter G05: PlotViwWindow

  ⇒ Casio Basic入門G06
     - Chapter G06: F-Line と 線のスタイル設定

  ⇒ Casio Basic入門G07
     - Chapter G07: 点線と ViewWindow

  ⇒ Casio Basic入門G08
     - Chapter G08: ViewWindow (直交座標系) の有効活用 / RclPictRclCapt の違い

  ⇒ Casio Basic入門G09
     - Chapter G09: ViewWindow と設定変数

  ⇒ Casio Basic入門G10
     - Chapter G10: Circle コマンド

  ⇒ Casio Basic入門G11
     - Chapter G11: PxlOn コマンド

  ⇒ Casio Basic入門G12
     - Chapter G12: PxlOff コマンド

  ⇒ Casio Basic入門G13
     - Chapter G13: PxlChg コマンド

  ⇒ Casio Basic入門G14
     - Chapter G14: PxlTest() コマンド

  ⇒ Casio Basic入門G15
     - Chapter G15: 


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


 


keywords: fx-5800Pfx-9860GIICasioBasicプログラミング入門プログラム関数電卓

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

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

Casio Basic入門59

Casio Basic入門
<目次>

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

 追記 2017/11/05


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

Chapter 10 - 中級

◆ Chapter 10 の目標: 3桁区切り出力 - 汎用サブルーチンの作成

前回: Casio Basic入門58 を見る


これまでに完成させた fx-5800P版 3桁区切りサブルーチンのソースを再掲します。

fx-5800P版 "高速3桁区切り出力・汎用サブルーチン":3DS
Z=0⇒Return

Int(log(Z))+1→K
(K≥4)+(K≥7)+(K≥10)→I

X→D:X→W
X=0⇒17-K-I←X
If X+K+I>17 Or K≥13
Then
X+K≥17⇒17-K→D
If K≥11:Then
2→D:X<2⇒X→D
W=0⇒2→D
IfEnd
Locate D,Y,Z
Return:IfEnd

X103Frac(Z÷X103)→U
Int(X103Frac(Z÷X106))→V
Int(X103Frac(Z÷X109))→W
Int(Z÷X109)→D

If K≤8:Then
Locate X,Y,X108W+X104V+U
I≥1⇒Locate X+K-2-(I=1),Y,","
I≥2⇒Locate X+K-6,Y,","
Else
X+K-6+(I≥3)→J
Locate J,Y,X107+X104V+U
Locate X,Y,X104D+W
Locate J+4,Y,","
Locate J,Y,","
I≥3⇒Locate X+K-9,Y,","
IfEnd


今回は、グラフ関数電卓への移植を試みます。

なお、fx-CG20 / CG50 と fx-9860GII は同じプログラムで完全に動作しますが、プログラム編集画面での表現が少し異なります。fx-CG20 / CG50 では [X10x] キーを押すと X10x と表記されます。これは fx-5800P も同じです。一方 fx-9860GII では同じキーが [EXP] と印刷されていて、プログラム編集画面では E と表現されます。

先ずは、fx-CG20 / CG50 での表現でプログラムを記述します。

Chapter 10-5
3桁区切りサブルーチン グラフ関数電卓版

グラフ関数電卓版 3DS の仕様
  1. 15桁対応:fx-5800P版のプログラムは、そのまま100%互換でグラフ関数電卓で動作します。しかし、1行が21桁あり fx-5800P の12桁対応では物足りなく感じる。そこで、15桁対応に拡張します。
  2. 変数を増やさない3DS で用いる変数は fx-5800P版と同じとする。メインルーチンで使う変数の制限をこれ以上厳しくしないことを優先的に考え、グラフ関数電卓版で使う変数を追加しない。

グラフ関数電卓版 3DS
具体的に変更した部分です。

前半の変更は、主に1行の桁数が16桁から21桁に変わるので、それに対応したもの。なお3桁区切りは12桁対応から15桁対応へ変えたことに伴う部分が一カ所ある。

後半の変更は、15桁対応への拡張に伴うもの。特に新たな変数を追加しないので一見煩雑に思えるが、12桁対応と同じロジックを拡張しただけ。

fx-5800P版のソースが分かれば難しくないと思うので、詳細はソースをみてください。


◆ fx-CG20 / CG50版
先ずは fx-CG20 / CG50版 を示します。fx-5800P版と異なる部分を赤文字で示します。

fx-CG20 / CG50版 "高速3桁区切り出力・汎用サブルーチン":3DS
Z=0⇒Return

Int(log(Z))+1→K
(K≥4)+(K≥7)+(K≥10)+(I≥13)→I

X→D:X→W
X=0⇒22-K-I→X
If X+K+I>22 Or K≥16
Then X+K≥2222-K→D
If K≥11:Then
7→D:X<2⇒X→D:W=0⇒7→D
IfEnd
Locate D,Y,Z
Return:IfEnd

X103Frac(Z÷X103)→U
Int(X103Frac(Z÷X106))→V
Int(X103Frac(Z÷X109))→W
Int(Z÷X109)→D

If K≤8:Then
Locate X,Y,X108W+X104V+U
I≥1⇒Locate X+K-2-(I=1),Y,","
I≥2⇒Locate X+K-6,Y,","
Else
X+K-6+(I≥3)+(I≥4)→J
Locate J,Y,X107+X104V+U
Locate X+(I≥4),Y,
X107Int (D÷X103)+X107Fac (D÷X103)+W
I≥4⇒Locate X,Y,Int (D÷
X103)
Locate J+4,Y,","
Locate J,Y,","
I≥3⇒Locate X+K-9+(I≥4),Y,","
I≥4⇒Locate X+K-12,Y,","
IfEnd


ダウンロード高速3桁区切り出力・汎用サブルーチン - 3DS (fx-CG20 / CG50版)
 ※ デバッグ・使いこなしテスト用プログラムもダウンロードできます。   


速度に最も影響を与える Locate コマンドの使用回数は、
  • 8桁以下の場合 (K≤8):3回 (fx-5800Pと同じ)
  • 9桁の場合 (K=9 かつ I=2):5回 (fx-5800Pと同じ)
  • 10~12桁の場合 (10≤K≤12 かつ I=3):6回 (fx-5800Pと同じ)
  • 13~15桁の場合 (13≤K≤15 かつ I=4):8回
となる。12桁までは回数は同じで、拡張した13~15桁の場合のみ2回増えることになる。

次に速度への影響を考えるべき論理演算の回数は、
  • 8桁以下の場合 (K≤8):3回 (fx-5800Pと同じ)
  • 9~15桁の場合 (9≤K≤15):7回 (fx-5800Pは2回)
なので、9~15桁では論理演算5回増え、fx-5800P ならば約 50m秒程度遅くなる計算。

しかし、グラフ関数電卓は fx-5800P より処理が圧倒的に速いので、この程度では fx-5800P よりも速く感じる

3DS src for fx-CG50 


fx-9860GII版
fx-9860GII 版も CG版と全く同じだが、X10x の編集画面上の表現が異なるだけだ。

fx-9860Gシリーズ版 "高速3桁区切り出力・汎用サブルーチン":3DS
Z=0⇒Return

Int(log(Z))+1→K
(K≥4)+(K≥7)+(K≥10)+(I≥13)→I

X→D:X→W
X=0⇒22-K-I→X
If X+K+I>22 Or K≥16
Then
X+K≥2222-K→D
If K≥11:Then
7→D:X<2⇒X→D
W=0⇒7→D
IfEnd
Locate D,Y,Z
Return:IfEnd

E3Frac(Z÷E3)→U
Int(E3Frac(Z÷E6))→V
Int(E3Frac(Z÷E9))→W
Int(Z÷E9)→D

If K≤8:Then
Locate X,Y,E8W+E4V+U
I≥1⇒Locate X+K-2-(I=1),Y,","
I≥2⇒Locate X+K-6,Y,","
Else
X+K-6+(I≥3)+(I≥4)→J
Locate J,Y,E7+E4V+U
Locate X+(I≥4),Y,
E7Int (D÷E3)+E7Fac (D÷E3)+W
I≥4⇒Locate X,Y,Int (D÷
E3)
Locate J+4,Y,","
Locate J,Y,","
I≥3⇒Locate X+K-9+(I≥4),Y,","
I≥4⇒Locate X+K-12,Y,","
IfEnd


ダウンロード高速3桁区切り出力・汎用サブルーチン - 3DS (fx-9860Gシリーズ版)
 ※ デバッグ・使いこなしテスト用プログラムもダウンロードできます。


3DS src for fx-9860GII 



Chapter 10 はこれで終わりです。

⇒ Casio Basic入門60 / Casio Basic入門G01 / 目次



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


 



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

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


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

Casio Basic入門57

Casio Basic入門
<目次>

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

 2017/11/04
追記 2017/11/05


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

Chapter 10 - 中級

◆ Chapter 10 の目標: 3桁区切り出力 - 汎用サブルーチンの作成

前回: Casio Basic入門56 を見る


前回までに作った3桁区切りサブルーチンは以下です。

前回作った "高速3桁区切り出力・汎用サブルーチン" fx-5800P版:3DS
Z=0⇒Return

Int(log(Z))+1→K
(K≥4)+(K≥7)+(K≥10)→I

X→D:X→W         
=======
If X+K+I>17 Or K≥13
Then
X+K≥17⇒17-K→D
If K≥11:Then        
エラー処理ルーチン
2→D:X<2⇒X→D
W=0⇒2→D
IfEnd
Locate D,Y,Z
Return:IfEnd       
=======

X103Frac(Z÷X103)→U
Int(X103Frac(Z÷X106))→V
Int(X103Frac(Z÷X109))→W
Int(Z÷X109)→D

If K≤8:Then
Locate X,Y,X108W+X104V+U
I≥1⇒Locate X+K-2-(I=1),Y,","
I≥2⇒Locate X+K-6,Y,","
Else
X+K-6+(I≥3)→J
Locate J,Y,X107+X104V+U
Locate X,Y,X104D+W
Locate J+4,Y,","
Locate J,Y,","
I≥3⇒Locate X+K-9,Y,","
IfEnd


今回は、右寄せ出力ができるオプションを追加します。




Chapter 10-3
3桁区切りサブルーチン fx-5800P版 右寄せ出力機能の追加

先ず最初に、簡単なサンプルプログラムを作って 3DS の動作を見てみます。

指定位置に3桁区切り出力

かけ算プログラム:3DS TEST
"A"?→A
"B"?→B
"C"?→C
"A×B×C="
ABC


これは、変数 ABC に値を入力させ、A×B×C を計算した結果を出力するプログラムです。

実行すると、

 A?

と表示されるので、例えば 12 と入力すると、A12 が格納され、

 A?
 12
 B?


と表示されます。次に 456 と入力すると、B456 が格納され、

 12
 B?
 45
 C?


と表示されます。最後に 789 と入力すると、C789 が格納され、さらに ABC の計算結果を表示します。

 45
 C?
 78
 A×B×C=
         42120


旧来の出力命令 は、改行して右寄せで出力しますが、慣れると見やすくて便利です。そこで、3桁区切り出力にも右寄せ出力をオプションで設定できるようにします。


右寄せで3桁区切り出力

右寄せ出力を指定する方法として、Prog "3DS" の直前の設定で、X0 を設定することにします。

赤文字で示す1行を追加するだけで、うまくゆきます。

右寄せ機能を追加した "高速3桁区切り出力・汎用サブルーチン" fx-5800P版:3DS
Z=0⇒Return

Int(log(Z))+1→K
(K≥4)+(K≥7)+(K≥10)→I

X→D:X→W
X=0⇒17-K-I→X
If X+K+I>17 Or K≥13
Then
X+K≥17⇒17-K→D
If K≥11:Then
2→D:X<2⇒X→D
W=0⇒2→D
IfEnd
Locate D,Y,Z
Return:IfEnd

X103Frac(Z÷X103)→U
Int(X103Frac(Z÷X106))→V
Int(X103Frac(Z÷X109))→W
Int(Z÷X109)→D

If K≤8:Then
Locate X,Y,X108W+X104V+U
I≥1⇒Locate X+K-2-(I=1),Y,","
I≥2⇒Locate X+K-6,Y,","
Else
X+K-6+(I≥3)→J
Locate J,Y,X107+X104V+U
Locate X,Y,X104D+W
Locate J+4,Y,","
Locate J,Y,","
I≥3⇒Locate X+K-9,Y,","
IfEnd


エラー処理ブロックでは、X の値を変数 DW に一旦コピーして、DW で必要な条件判定を行い X の値を変更せずにエラー時の出力を実行するようにしています。今回追加したのは、X=0 の時に単に X の値 (出力開始桁) を変更するだけなので、エラー処理ルーチンに何の影響も与えません。従って、上記の1行を追加するだけで右寄せ機能を実装できます。



検証します。

上のかけ算プログラムの最後の2行を3桁区切りするように変更します。

かけ算プログラム:3DS TEST
"A"?→A
"B"?→B
"C"?→C
"A×B×C="
0→X:4→Y:ABC→Z
Prog "3DS"

右寄せで3桁区切り出力させるために 0→X と設定しています。

実行して、A=12、B=45、C=78 を入力すると、以下の画面になり、

 45
 C?
 78
 A×B×C=   42,120


乗算結果 A×B×C が右寄せで3桁区切り出力されています。


デバッグ用プログラムを改造 - 3DS DEBUG2
以下のようなデバッグしやすいプログラム 3DS DEBUG2 を作りました。表示開始桁 X と 出力数値 Z のどちらかを変更すると、画面スクロールせずに4行目に結果が出力されるようにしています。条件を変えて色々と検証して、管理人はこれを使って問題ないことを確認しています。

3DS DEBUG2 Src for fx-5800P 

入力ボックス INPI を利用して画面構成を壊さないようにしているので、出力位置が1桁ずれてもスグに分かって便利です。




fx-5800P 版の高速3桁区切り出力・汎用サブルーチン完成版を改めて示します。

※ ダウンロード: 3DS for fx-5800P ソースファイル (pdfファイル)

3DS_src_fx5800P.jpg 




次回は、3DS の使いこなしを紹介します。


つづく...

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



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


 



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

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



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

Casio Basic入門56

Casio Basic入門
<目次>

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

 2017/11/03
追記修正 2017/11/05


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

Chapter 10 - 中級

◆ Chapter 10 の目標: 3桁区切り出力 - 汎用サブルーチンの作成

前回: Casio Basic入門55 を見る


今の 3DS の動作を調べるために簡単なデバッグ用プログラムを作って実際の動作を調べ、改善を試みます。

Chapter 10-2
3桁区切り出力サブルーチンの評価と改善

先ず以下のようなデバッグ用プログラムを作ります。

デバッグ用プログラム

3DS DEBUG
Do
Cls
"X"?→X
"Z"?→Z
""
4→Y
Prog "3DS"
LpWhile Getkey=47



このデバッグ用プログラムを fx-5800P で実行し、設定 (XZ) に種々異なる値を入力し、期待通りの動作かどうかを確かめます。


1)
X = 3、Z = 1234567890 (10桁) を入力すると、3桁4行目から
  1,234,567,890
と出力されます。

2)
では、X = 5 とし、Z は同じ Z = 1234567890 (10桁) と入力すると、5桁4行目から
  1234567890
と3桁区切りせず出力します。3桁区切り出力だと1行16文字に収まらない場合はこのようになります (コード通り)。

3)
Xを増やし、X = 8、Zは同じ Z = 1234567890 (10桁) とすると、8桁4行目から
  123456789
となり、右端の 0 が押し出されて消えています。

4)
X をさらに増やし、X = 12、Zは同じ Z = 1234567890 (10桁) とすると、12桁4行目から
  12345
となり、現在のままだと問題です。


◆ 追加仕様1:
右にはみ出る場合は、X で指定した桁を無視して、右寄せで全ての桁を出力する。


そこで、3DS 前半にあるエラー処理ブロック (以下) に着目し、

If X+K+I>17
Then
Locate X,Y,Z
Return:IfEnd


以下のように赤文字の1行を追加します。

If X+K+I>17
Then
X+K≥17⇒17-K→X
Locate X,Y,Z
Return:IfEnd


3桁区切りすると1行16文字に収まらない時は、X+K≥17 になり、この場合は3桁区切りしない値 (Z) をそのまま右寄せで出力するので、出力開始桁である X17-K→X で再設定します。

これを検証します。

3)'
X = 8、Zは同じ Z = 1234567890 とすると、7桁4行目から
  1234567890
と出力され、期待通りの動作です。

4)'
X = 12、Zは同じ Z = 1234567890 とすると、7桁4行目から
  1234567890
と期待通りの出力になります。

=====

エラー処理の結果、3桁区切りだと行あふれになるので、区切り文字無しの正しい値が出力される仕様です。3桁区切りできない事を示すエラー表示の代わりです。しかし正しい値は表示します。汎用サブルーチンは控えめが良いのです。

このような控えめなエラー表示は、メインルーチン内で出力位置や桁数についての再検討を促す意味もある...といったコンセプトです。

では、11桁以上を出力する場合を調べます。

5)
X = 2、Z = 123456543210 (12桁) と入力すると、2桁4行目から
  123,456,543,210
と出力されます。ちょうど右端に出力されています。

6)
X を1つ増やし X = 3、Zは同じで Z = 123456543210 (12桁) を入力すると、3桁4行目から
  1.234565432x101
と出力されます。
本来、1.234565432x1011 と表示されるべきなので、右端の1桁が押し出されて表示されていません。
出力開始桁は設定通りの3桁目。なおエラー処理ルーチンでは Locate X,Y,Z で出力しているので、11桁以上は電卓の仕様に従って指数表示になっています。 

7)
X をさらに1つ増やして X = 4、Zは同じで Z = 123456543210 (12桁) とすると、4桁4行から
  1.234565432x10
と出力され、右端の2桁が押し出されて表示されていません。

これで、新たな問題が明らかになりました。指数表示は電卓の仕様として、最大15桁です。そこで指数表示する場合 (K≥11) 最大15桁が必ず表示されるように変更します。


◆ 追加仕様2:
エラー時の出力が指数表示になる場合 (K≥11 のとき)、15桁を確実に出力する。


fx-5800P は1行16文字なので、指数表示の出力開始桁 (X) は1か2です。そこで、K≥11 の場合、さらに出力開始桁が 2 を超える (X>2) のとき X2 に固定します。

具体的には、エラー処理ブロック

If X+K+I>17
Then
X+K≥17⇒17-K→X
Locate X,Y,Z
Return:IfEnd


に3行(赤文字)を追加します。

If X+K+I>17
Then
X+K≥17⇒17-K→X
If K≥11:Then
X>2⇒2→X
IfEnd

Locate X,Y,Z
Return:IfEnd


検証します。

6)'
X = 3、Z = 123456543210 と入力すると、2桁4行目から
  1.234565432x1011
と期待通りに出力されます。

7)'
X = 4、Z は同じ Z = 123456543210 とすると、2桁4行目から
  1.234565432x1011
と、期待通りに出力されます。

=====

入力桁をもっと大きくしてみます。

8)
X = 3、Z = 1234567890123456 (16桁) を入力してみると、1桁4行目から
  1.23456789x1015
と出力されます。
指定された動作は、1桁目から出力ではなくて2桁目の筈です。

9)
X = 3、Z = 12345678901234567 (17桁) を入力すると、Locate コマンドで Argument ERROR が発生します。


この問題を確認するために、エラー処理のコードを細かくみてみます。

If X+K+I>17
Then
X+K≥17⇒17-K→X
If K≥11:Then
X>2⇒2→X
IfEnd
Locate X,Y,Z
Return:IfEnd


8) の場合は、K = 16、X = 2、I = 4 なので、赤文字で示した1つめ;
  X+K≥17⇒17-K→X
が実行されると、X = 1 となり、赤文字で示した2つめ;
  X>2⇒2→X
は実行されないので、X = 1 となり、これは期待した動作でないことが分かります。

赤文字の1つめで X が変更されたから、本来実行する必要のある赤文字の2つめが動作しなかったと考えます。そこで、エラー処理ブロックでは、X を一旦 変数 D にコピーしておき、赤文字の2カ所の評価結果を D へ格納し、Locate D,Y,Z を実行すれば、2つの評価が正しく実行されます。

一旦、エラー処理ブロックを以下のように変更します。

X→D
If X+K+I>17
Then
X+K≥17⇒17-K→D
If K≥11:Then
X>2⇒2→D
IfEnd
Locate D,Y,Z
Return:IfEnd


ところが、このコードを 9) の17桁入力のケース (K=17) に適用すると、まだ問題が残っていることが分かります。

もし、入力桁数が 17桁以上、つまり K が 17 以上の時、
  X+K≥17⇒17-K→D
が実行されると D が 0以下になり、Locate D,Y,ZArgument ERROR となることが確認できました。

K17 以上の場合は、必ず If K≥11 の中の処理へ進むので、X>2⇒2→D を変更してこの問題を解決します。

D→X
If X+K+I>17
Then
X+K≥17⇒17-K→D
If K≥11:Then
2→D:X<2⇒X→D
IfEnd
Locate D,Y,Z
Return:IfEnd


入力が11桁以上の場合は、出力開始桁を強制的に D = 2 にしておいて、X<2 の時つまり 出力開始桁が1の時は例外的に D = 1 に変更する...条件判定を X>2 から X<2 へ発想を逆転しました。


◆追加仕様3:
入力が17桁以上のとき指数表示になるが、指定桁 X からの出力 or 右寄せ出力にする

検証します。

8)'
X = 3、Z = 1234567890123456 (16桁) と入力すると、2桁4行目から
  1.234565432x1011
と、期待通りに動作します。

9)'
X = 3、Z = 12345678901234567 (17桁) とするとき、2桁4行目から
  1.234567654321x1012
と、今度も期待通りに動作します。


もう少し実験を進めます。

10)
X = 1、Z = 1234567654321 (13桁) を入力すると、1桁4行目から
  1234,567,654,321
と表示されます。3DS は12桁対応なので仕方ないところです。

このままにするか、12桁を超えるとエラー処理ブロックで処理して指数表示するか、どちらが良いかは好みの分かれるところだと思います。

管理人の趣味では、汎用サブルーチンとして完成させるためには、上記のような13桁出力させずにエラー処理ブロックで指数表示させるようにプログラムを変更しようと思います。この変更は、ユーザーの趣味に合わせて実施しなくても良いかも知れません。

変更は単純で、

エラー処理ブロックに入るところの If 文を変更するだけです。

If X+K+I>17



If X+K+I>17 Or K≥13

に変更するだけです。




最後に少しだけ高速化してみます。

無駄な乗算処理を省略する
1X1061X109 など 1X10 が12回使われています。12回1の乗算が使われていて、これは無駄です。12回の乗算を省略すれば速度向上に多少寄与します。 1X10 の頭の 1 を全て消します。


論理演算を削減する
最後のブロックをよく見ると、重複したコードがあります

Else
Locate X+K-6+(I≥3),Y, X107+X104V+U
Locate X,Y,X104D+W
Locate X+K-2+(I≥3),Y,","
Locate X+K-6+(I≥3),Y,","
I≥3⇒Locate X+K-9,Y,","
IfEnd


(I≥3) が3回使われています。論理演算は 10ms 程度かかる重い処理なので、実行回数を減らすと高速化に寄与します。そこで、

X+K-6+(I≥3)→J

として変数 J を導入し、以下のように変更すると 20ms 程度は処理時間が短くなります。

Else
X+K-6+(I≥3)→J
Locate J,Y, 1X107+1x104V+U
Locate X,Y,1X104D+W
Locate J+4,Y,","
Locate J,Y,","
I≥3⇒Locate X+K-9,Y,","
IfEnd





ここまでをまとめます。


高速3桁区切り出力・汎用サブルーチン:3DS
Z=0⇒Return

Int(log(Z))+1→K
(K≥4)+(K≥7)+(K≥10)→I

X→D
If X+K+I>17 Or K≥13
Then
X+K≥17⇒17-K→D
If K≥11:Then
2→D:X<2⇒X→D
IfEnd
Locate D,Y,Z
Return:IfEnd

X103Frac(Z÷X103)→U
Int(X103Frac(Z÷X106))→V
Int(X103Frac(Z÷X109))→W
Int(Z÷X109)→D

If K≤8:Then
Locate X,Y,X108W+X104V+U
I≥1⇒Locate X+K-2-(I=1),Y,","
I≥2⇒Locate X+K-6,Y,","
Else
X+K-6+(I≥3)→J
Locate J,Y,X107+X104V+U
Locate X,Y,X104D+W
Locate J+4,Y,","
Locate J,Y,","
I≥3⇒Locate X+K-9,Y,","
IfEnd




次回は、もうひとつ機能を追加して、汎用サブルーチンとして仕上げる予定です。


つづく...

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



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


 



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

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


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

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

やす (Krtyski)

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


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

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

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


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

ブロとも申請フォーム

この人とブロともになる

QRコード
QR