Casio Basic入門55

Casio Basic入門
<目次>

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

 2017/11/03
訂正 2017/11/04


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


前回: Casio Basic入門54 を見る


Chapter 10 - 中級

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

大きな数が出力された時、例えば、

59265358

だと数の大きさがよく分からないのですが、

59,265,358

だと、5千9百万くらいとスグに分かります。

Casio Basic が使えるプログラム電卓には3桁区切り出力の機能がありません。そこで Casio Basic で作るプログラムで、

Locate X,Y,Z

の代わりに、

Prog "3DS"

と記述すると3桁区切り出力できるサブルーチン 3DS を作ります。3DS は少し機能追加してより一般的に使える汎用サブルーチンとして仕上げます。


前回 (Chapter 9) の後半で、sentaro様ご提案の高速出力する3桁区切りサブルーチンを取り上げ、さらっと紹介しています。これは非常によく考えられたロジックなので、今回はこのプログラムを掘り下げた上で、fx-5800P用汎用サブルーチンとして仕上げ、グラフ関数電卓用に拡張します。
  • fx-5800P用高速3桁区切りサブルーチンの詳細を紹介
  • 機能追加を必要最低限の改造で行って fx-5800P用の12桁対応・汎用サブルーチンとしてまとめる
  • グラフ関数電卓用に移植し、15桁対応に機能拡張



3桁区切り出力サブルーチンの使い方
サブルーチンのプログラム名は、短い方が入力が楽で、3-Digit Separator (3桁区切り) から 3DS としました。

Locate X,Y,Z の代わりに Prog "3DS" と書いて3桁区切りを実現します。但し Locate コマンドでは、X, Y Z の3つのパラメータを渡せますが、サブルーチン 3DS にはパラメータが渡せません。そこで、Prog "3DS" 実行の直前に、変数 X, Y, Z を設定します。

Casio Basic の特性として、メモリ内にある全てのプログラムで変数が共有され、全ての変数は "大域変数 (グローバル変数)" となっています。そこで、3DS を実行する直前に X, Y, Z に値を格納し、それを 3DS で利用します。

・変数 X は、3桁区切り出力を開始する桁、Locate X,Y,ZX と同じ
・変数 Y は、3桁区切り出力を開始する行、Locate X,Y ZY と同じ
・変数 Z は、3桁区切り出力する整数、Locate X,Y,ZZ と同じ

例えば、123456789012 を 2桁3行に3桁区切り出力するために、

  2→X:3→Y:123456789012→Z
  Prog "3DS"


と書けば、2桁3行目に 123,456,789,012 と出力します。

或いは、予め 123456789012 が変数 A に格納されていると、

  2→X:3→Y:A→Z
  Prog "3DS"


と記述すると、同じ出力になります。


使用上の注意点
3DS では、X, Y, Z に加えて、以下の変数を使っています。

Z: 3桁区切りする数値
X: 出力する桁
Y: 出力する行
-----
K: 数値の桁数
I: 区切り文字","の数
U: 最下位3桁の数値
V: 4~6桁の3桁の数値
W: 7~9桁の3桁の数値
D: 10桁目以上の数値
J: 9桁目区切り文字位置

3DS が走るとこれらの変数の値が変化します。メインルーチンでこれらの変数を使う時は、3DS で値が変わっても問題無いように使います。一番簡単な方法は、メインルーチンで上記変数名を使わないことです。

既に作ってあるプログラムに3桁区切り出力機能を追加する場合 (私自身はこのケースが多い) は、上記と同じ変数名を別の変数名に変えるのが確実です。同じ変数名を多く使ったメインルーチンで3桁区切り出力機能を追加するときは、メインルーチンをよく調べて、変数の値を保持させたい有効範囲の外で 3DS を使う場合は、同じ変数を使っても問題ありません。

処理速度が遅くなるが万能な方法もあります。配列変数 (fx-5800P) や行列 (グラフ関数電卓) を使って、3DS を使う前にかち合う変数を配列変数 (行列) にコピー (待避) し、3DS 使用後に 配列変数 (行列) から元の変数へコピー (復帰) します。この方法は柔軟に使える反面、配列変数 (行列) は処理が遅いので、高速性が必要なプログラムには向きません。

以上の方法をうまく組み合わせると、既存のプログラムで3桁区切り出力が実現できます。



前回さらっと紹介した高速版3桁区切り出力サブルーチンについて、詳細をみてゆきます。

Chapter 10-1
高速版3桁区切り出力サブルーチンの特長

高速表示版は、12行+α の簡潔なプログラムですが、幾つかの大きな特長があります。

[ロジック]
Locate コマンドの使用回数を大幅に抑えることで、高速出力を実現しています。
例えば12桁の数 123456789012 を3桁区切り出力するとします。
  1. 最初に、下から3桁づつ 012789456 を切り出し、残りの桁 123 も切り出します。
  2. 次に、1x107 + 789x104 + 012 = 17890012 を算出。3桁の数の間に 0 を挟み込んだところがミソ!
  3. さらに、123x104 + 456 = 1230456 を算出。ここでも3桁の数の間に 0  を挟み込んでいる。
  4. 2回の Locate コマンドで表示位置をずらして、これら2つの数が繋がるように出力 ⇒ 123045617890012 
  5. ここで、Locate 一回で出力するのは8桁以下なので、指数表示にならないのも重要なポイント!
  6. つなぎの 01 の位置に Locate コマンド3回で区切り文字 "," を1つづつ出力 ⇒ 123,456,789,012 となる

[特長1]Locate 使用回数を減らして高速化
区切り文字が入る位置に予め 0 や 1 で繋いで数値を出力し、あとでつなぎの 0 や 1 の位置に区切り文字を上書きすることで、Locate 使用回数を減らしています。 

[特長2]:指数表示を抑える
上の一連の処理で、実際の1回の計算で算出された数の最大のものは、1x107 (8桁) である点が重要です。Casio Basic が走るCasioの電卓では、出力する数の桁数が11桁以上になると強制的に指数表示になる仕様で、指数表示になってしまうと区切り文字の付けようがありません。Locate で出力する数は必ず10桁以下にする必要があります。

[特長3]:本来指数表示になる11桁以上の3桁区切りが可能
一回の Locate コマンドでの出力を10桁以下の数に限定し、11桁より上位の桁は、出力位置をずらして再度 Locate で繋がるように出力するロジックを採用することで、11桁以上の出力桁数に柔軟に対応できるのも特長です。 


具体的にコードを理解してゆきます。
ここで使っている関数は、Int(Frac(log(x10 です。
ここで 1x106 は "1かける10の6乗" (=1,000,000) です。

高速版3桁区切り 3DS
Z=0⇒Return Zがゼロの時は何もしないでメインルーチンに戻る

Int(log(Z))+1→K


Z に格納された数の桁数を求める (K)
(K≥4)+(K≥7)+(K≥10)→I

必要な区切り文字の数を求める (I)。論理演算式は、真なら1,偽なら0の値を持つ特性を利用し、( ) の中は0か1なので、この式で区切り文字の数が算出できる。
If X+K+I>17
Then
Locate X,Y,Z
Return:IfEnd





出力開始桁 (X) と桁数 (K) と 区切り文字数 (I) の和は出力結果の右端の桁。この和が17 を超える時は、1行から溢れて区切り文字出力が正しくできない。この場合は、単純に元の数 Z を区切り文字無しで出力する。
1X103Frac(Z÷1X103)→U
Int(1X103Frac(Z÷1X106))→V
Int(1X103Frac(Z÷1X109))→W
Int(Z÷1X109)→D


 



下位から3桁づつ切り取る。一番下位の3桁が U、次が VWと続く。D は10桁目より上位の数で3桁とは限らない (4桁以上のケースもある)。
 
 
If K≤8:Then
Locate X,Y,1X108W+1X104V+U
I≥1⇒Locate X+K-2-(I=1),Y,","
I≥2⇒Locate X+K-6,Y,","









桁数が8以下の時は、区切り文字の位置に 0 を挟んだ数を作るために 最上位2桁(W)を一旦 x108 倍する処理がある。2桁の x108 倍は10桁になるが、一気に10桁の数を Locate で出力しても指数表示にはならない。そこで 桁数が8以下の時の Locate を3回用いる軽い処理をここに記述する。
Else
Locate X+K-6+(I≥3),Y, 1X107+1X104V+U
Locate X,Y,1X104D+W
Locate X+K-2+(I≥3),Y,","
Locate X+K-6+(I≥3),Y,","
I≥3⇒Locate X+K-9,Y,","
IfEnd


 
 
 
 
 



桁数が9桁以上の場合の処理。具体的には冒頭に示した処理。
このロジックでは最大12桁対応になっている。Locate を5回用いており、依然として軽快に動作する。
 
 
 
 
 

ここまでが、前回、Chapter 9 で紹介した 高速版3桁区切り出力サブルーチンの詳細です。



汎用性のあるサブルーチンとしては、上の 3DS には少し問題があります。そこで次回は、評価用プログラムを作って、実際の動作を調べ、改善を行います。



つづく...

Casio Basic入門56 / Casio 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