テンキーの数字からキーコードへの変換式
これまで、色々とプログラムを作っている際、押したテンキーの数字から、そのキーのキーコードを導き出す簡単な計算式があれば良いと思いつつも、そのようなものは考えついていませんでした。
そこで、配列変数を使って、以下のように対応を付ける方法を使っています。
10→DimZ
35→Z[1]:36→Z[2]
37→Z[3]:21→Z[4]
22→Z[5]:23→Z[6]
31→Z[7]:32→Z[8]
33→Z[9]:25→Z[0]
この場合は、テンキーの数字を N とすると、キーコードは Z[N] で得られます。
fx-5800P では、配列変数へのアクセスは20ms 程度の時間がかかるので、上のように10個の配列変数を初期化するのに 200ms (0.2秒) かかります。それだけでなく、プログラム中で Z[N] を使えば、そのたびに 20ms の時間がかかります。実際はこの程度の時間を許容するしかないと思っています。
もし簡潔で高速に計算できるなら、テンキーの数字からキーコードを計算して使えばよく、配列変数の遅さを解消できる可能性があるので、頭の隅っこで引っかかっていました。
ところで、PCで使う Windows プログラムを作っていて、アイディアがひらめきました。全然違うことに頭を使っていると、昔の疑問へのヒントが突然現れる...人間の脳の働きは面白いと思います。
そして、fx-5800P のテンキーの数字からキーコードを求める式ができそうな気がしたので、整理してみました。
このように、3色で区別したグループ内では、それぞれ共通点があり、上の表に示したように、A と B が 0 か 1 になれば、17+N+10A+7B でキーコードが計算できることが分かりました。
従って、A と B を高速に求める計算方法が見つかれば、今後のプログラムで利用できます。
A については、単調減少する反比例のグラフ y = a/x +b をヒントにして、x = 1, 2, 3 の時 1≦y≦1.9 となり x = 4, 5, 6, ,7, 8, 9 の時 0 < y < 1 となる条件から a と b を求め、N が 1, 2, 3 の時に A が 1 で、それ以外は A が 0 となる式を決めました。
Int(1.35÷N+ 0.55)→A
B については、x = 4, 5, 6 の時 0< y < 1 となり、x がそれ以外の時 1≦ y < 2 となる使えそうなグラフは何かと考えてみて、取りあえず三角関数くらいしかなさそうだと考え、N = 1 ~ 9 を余弦関数 (cos) の1周期としてみると、
cos [2π (N-1)/8]
ここで、N = 3 , 7 で丁度 0 となり、N= 1, 9 で丁度 1 となります。つまり、N = 4~6 で 0 以下となり、それ以外は正の数となるので、目的に合うことが分かります。あとは、係数をあれこれ検討すればよく、以下の式が出来ました。
Int(1+0.9cos((N-1)π÷4))→B
余弦関数 cos で N=1 の時から N=9 の時を1周期となるようにして、あとは Int( ) で 0 か 1 かになるように cosの振幅係数を 0.9 とし、グラフ全体を 1 だけ持ち上げるようにしたわけです。
以上をまとめると、テンキー N のキーコード K は、
17+N+10Int(1.35÷N+0.55)+7Int(1+0.9cos((N-1)π÷4)))→K
と、取りあえず計算で求められることが分かりました。角度には Rad (ラジアン) を指定する必要があります。以下のプログラムは、1~9までのテンキーを押すと、計算だけでキーコードを表示します。
計算でテンキーのキーコードを求めるプログラム
Rad
Lbl 0
"N"?→N
17+N+10Int(1.35÷N+0.55)+7Int(1+0.9cos((N-1)π÷4))◢
Goto 0
この計算に要する時間を簡単に測定するために、以下の2つのプログラムの処理時間を比較してみます。
プログラムA
Rad
100→C:1→N
Lbl 0
17+N+10Int(1.35÷N+0.55)+7Int(1+0.9cos((N-1)π÷4))
N=9⇒0→N:Isz N
Dsz C
Goto 0
"DONE"
プログラムB
Rad
100→C:1→N
Lbl 0
N=9⇒0→N:Isz N
Dsz C
Goto 0
"DONE"
この2つのプログラムの処理時間の差が、換算式の処理時間とします。その結果、この計算には 152ms もかかることが分かり、残念ながら配列変数を使う方がはるかに速いことになります。実用性を考えれば、この方法を採用できません。なおテンキー 0 には対応していません。
今後、A と B の計算が速くできる方法が見つかれば実用可能になります。ご提案があれば、是非聞かせてください。
記録に残す意味も含めて、本エントリーをアップします。
なお、If文や ⇒命令を使って A と B を決めて計算すれば、当然ながら処理速度は速くなりますが、キーコードが必要な時に一々 If文や ⇒命令を使ったロジックを採用するのは、Casio Basicプログラムが途端に見づらくなります。またこのロジックをサブルーチンにして使う方法もありますが、fx-5800P ではサブルーチンの呼び出しのオーバーヘッドが大きく、処理時間がかかるので採用しづらくなります。従って、配列変数か計算式の速い方を採用するのが現実的でしょう。
応援クリックをお願いします。励みになるので...
そこで、配列変数を使って、以下のように対応を付ける方法を使っています。
10→DimZ
35→Z[1]:36→Z[2]
37→Z[3]:21→Z[4]
22→Z[5]:23→Z[6]
31→Z[7]:32→Z[8]
33→Z[9]:25→Z[0]
この場合は、テンキーの数字を N とすると、キーコードは Z[N] で得られます。
fx-5800P では、配列変数へのアクセスは20ms 程度の時間がかかるので、上のように10個の配列変数を初期化するのに 200ms (0.2秒) かかります。それだけでなく、プログラム中で Z[N] を使えば、そのたびに 20ms の時間がかかります。実際はこの程度の時間を許容するしかないと思っています。
もし簡潔で高速に計算できるなら、テンキーの数字からキーコードを計算して使えばよく、配列変数の遅さを解消できる可能性があるので、頭の隅っこで引っかかっていました。
ところで、PCで使う Windows プログラムを作っていて、アイディアがひらめきました。全然違うことに頭を使っていると、昔の疑問へのヒントが突然現れる...人間の脳の働きは面白いと思います。
そして、fx-5800P のテンキーの数字からキーコードを求める式ができそうな気がしたので、整理してみました。
テンキー N | キーコード | キーコード計算 | A | B | 共通の計算式 |
1 | 35 | = 17+N+17 | 1 | 1 | 17+N+10A+7B |
2 | 36 | = 17+N+17 | 1 | 1 | 17+N+10A+7B |
3 | 37 | = 17+N+17 | 1 | 1 | 17+N+10A+7B |
4 | 21 | = 17+N+0 | 0 | 0 | 17+N+10A+7B |
5 | 22 | = 17+N+0 | 0 | 0 | 17+N+10A+7B |
6 | 23 | = 17+N+0 | 0 | 0 | 17+N+10A+7B |
7 | 31 | = 17+N+7 | 0 | 1 | 17+N+10A+7B |
8 | 32 | = 17+N+7 | 0 | 1 | 17+N+10A+7B |
9 | 33 | = 17+N+7 | 0 | 1 | 17+N+10A+7B |
このように、3色で区別したグループ内では、それぞれ共通点があり、上の表に示したように、A と B が 0 か 1 になれば、17+N+10A+7B でキーコードが計算できることが分かりました。
従って、A と B を高速に求める計算方法が見つかれば、今後のプログラムで利用できます。
A については、単調減少する反比例のグラフ y = a/x +b をヒントにして、x = 1, 2, 3 の時 1≦y≦1.9 となり x = 4, 5, 6, ,7, 8, 9 の時 0 < y < 1 となる条件から a と b を求め、N が 1, 2, 3 の時に A が 1 で、それ以外は A が 0 となる式を決めました。
Int(1.35÷N+ 0.55)→A
B については、x = 4, 5, 6 の時 0< y < 1 となり、x がそれ以外の時 1≦ y < 2 となる使えそうなグラフは何かと考えてみて、取りあえず三角関数くらいしかなさそうだと考え、N = 1 ~ 9 を余弦関数 (cos) の1周期としてみると、
cos [2π (N-1)/8]
ここで、N = 3 , 7 で丁度 0 となり、N= 1, 9 で丁度 1 となります。つまり、N = 4~6 で 0 以下となり、それ以外は正の数となるので、目的に合うことが分かります。あとは、係数をあれこれ検討すればよく、以下の式が出来ました。
Int(1+0.9cos((N-1)π÷4))→B
余弦関数 cos で N=1 の時から N=9 の時を1周期となるようにして、あとは Int( ) で 0 か 1 かになるように cosの振幅係数を 0.9 とし、グラフ全体を 1 だけ持ち上げるようにしたわけです。
以上をまとめると、テンキー N のキーコード K は、
17+N+10Int(1.35÷N+0.55)+7Int(1+0.9cos((N-1)π÷4)))→K
と、取りあえず計算で求められることが分かりました。角度には Rad (ラジアン) を指定する必要があります。以下のプログラムは、1~9までのテンキーを押すと、計算だけでキーコードを表示します。
計算でテンキーのキーコードを求めるプログラム
Rad
Lbl 0
"N"?→N
17+N+10Int(1.35÷N+0.55)+7Int(1+0.9cos((N-1)π÷4))◢
Goto 0
この計算に要する時間を簡単に測定するために、以下の2つのプログラムの処理時間を比較してみます。
プログラムA
Rad
100→C:1→N
Lbl 0
17+N+10Int(1.35÷N+0.55)+7Int(1+0.9cos((N-1)π÷4))
N=9⇒0→N:Isz N
Dsz C
Goto 0
"DONE"
プログラムB
Rad
100→C:1→N
Lbl 0
N=9⇒0→N:Isz N
Dsz C
Goto 0
"DONE"
この2つのプログラムの処理時間の差が、換算式の処理時間とします。その結果、この計算には 152ms もかかることが分かり、残念ながら配列変数を使う方がはるかに速いことになります。実用性を考えれば、この方法を採用できません。なおテンキー 0 には対応していません。
今後、A と B の計算が速くできる方法が見つかれば実用可能になります。ご提案があれば、是非聞かせてください。
記録に残す意味も含めて、本エントリーをアップします。
なお、If文や ⇒命令を使って A と B を決めて計算すれば、当然ながら処理速度は速くなりますが、キーコードが必要な時に一々 If文や ⇒命令を使ったロジックを採用するのは、Casio Basicプログラムが途端に見づらくなります。またこのロジックをサブルーチンにして使う方法もありますが、fx-5800P ではサブルーチンの呼び出しのオーバーヘッドが大きく、処理時間がかかるので採用しづらくなります。従って、配列変数か計算式の速い方を採用するのが現実的でしょう。
応援クリックをお願いします。励みになるので...