fx-991ES PLUS 2nd edition の概要

 
2021/01/16
修正 2021/01/31


Casio fx-991ES PLUS 2nd edition - 摸倣品対策モデル

日本では 2005年1月に発売された fx-991ES は、fx-993ESfx-995ES とバージョンアップされた。fx-993ES に対応するヨーロッパモデルが fx-991ES PLUS であり、それがリニューアルされ、fx-991ES PLUS 2nd edition と名付けられた。今回はこのモデルを紹介する。

2nd edition と名付けられるモデルは、主に中国メーカーによる摸倣品対策のために、正規品であることを示す機能が追加され、それ以外は機能の変更はなく、デザインが変更されている。

ところで、fx-991ES は、数式通りの入力を実現する Natural-VPAM (教科書通り数式自然入力) を搭載した最初のカシオ関数電卓であった。
カシオ電卓総合カタログ 2005年1月版

日本では、fx-991ES の後継モデルが fx-993ES、さらに進化したモデルが fx-995ES であった。ESモデルの 2nd edition の国内発売モデルは fx-375ES A だ。

ヨーロッパでは、fx-991ES の後継は、fx-993ES と同じデザインの小型化・薄型化されたボディに収められた fx-991ES PLUS という名称が与えられている。細かい機能は fx-993ES と異なる。fx-995ES に対応するモデルは、同じデザインのボディで機能追加された fx-991ES PLUS C であった。この地域での 2nd edition モデルは fx-991ES PLUS 2nd eidition (日本の fx-993ES 相当)と fx-991ES PLUS C 2nd edition (日本の fx-995ES 相当、北米の fx-115ES PLUS 2nd edition と同じ) が2019年に発売された。

北米では、fx-991ES ではなく fx-115ES として発売された。その後継は fx-115ES PLUS で、その機能は日本モデルの fx-995ES に相当する。機能をとほぼ同じ機能で発売された。この地域での 2nd edition モデルは、fx-115ES PLUS 2nd edition が2019年に発売された。この機能は 日本モデルの  fx-995ES に相当する。

fx-991ESfx-911ES PLUS fx991es_2
     fx-991ES       fx-991ES PLUS    fx-991ES PLUS 2nd edition
    (日本モデル)     (欧州モデル)      (欧州モデル)

日本国内でのESモデルの fx-993ES の機能を引き継いだのが、fx-991ES PLUS 2nd edition で、これは日本国内では発売されていない。

Natural-VPAM に対応した ESシリーズは、最初のモデル fx-991ES から、地域によって進化の経路が下記のように異なる。
地域  ESモデル進化1  ESモデル進化2  ESモデル摸倣対策品
日本 fx-991ES⇒ fx-993ES⇒ fx-995ESfx-375ES A
欧州 fx-991ES⇒ fx-991ES PLUS
⇒ fx-991ES PLUS C    
fx-991ES PLUS 2nd edition
fx991ES PLUS C 2nd edition
北米 fx-115ES⇒ fx-115ES PLUSfx-115ES PLUS 2nd edition
※ これまで調べた範囲での各地域ごとのモデル展開。北米モデルは常に欧州モデルより少し多機能で、安い設定になっている。

カシオ関数電卓の分類
カシオの関数電卓は、以下のように世代に合わせて MSモデル ⇒ ESモデル ⇒ EXモデルなどと区分けされている。これらのモデル以外の関数電卓、ならびにプログラム関数電卓やグラフ関数電卓も下表に分類する。 

  世 代表示行数入力方式出力方式代表的機種 (摸倣対策品は赤文字)
第1世代1行表示置数後に関数入
置数と計算結果fx-260 Solar II
FX-502P, FX-602P
 
第2世代
  (MSモデルなど)
2行表示数式通り入力
(VPAM / S-VPAM)
入力表示行と結果出力行を
分ける
fx-991s, fx-991W, fx-991MS
fx-991MS 2nd edition
fx-290A

FX-603P, fx-4000P
fx-4500P, fx-4800P
fx-7000G, CFX-9850Gシリーズ
fx-7400GIII
 
第3世代
  (ESモデルなど)
複数行表示教科書通り
数学自然入力
(Natural-VPAM)
数学自然表示
(積分や総和記号入力も)
fx-991ES, fx993ES, fx-995ES
fx-991ES PLUS
fx-991ES PLUS C
fx-115ES PLUS
fx-991ES PLUS 2nd edition
fx-991ES PLUS C 2nd edition
fx-115ES PLUS 2nd edition
fx-375ES A

fx-5800P, fx-9860Gシリーズ
fc-9750GIII
 
第4世代
  (EXモデルなど)
高精細
複数行表示
教科書通り
数学自然入力
(Natural-VPAM)
数学自然表示
(積分や総和記号入力も)
fx-JP900, fx-JP700, fx-JP500
fx-991EX

fx-CG20, fx-CG50


模倣品対策

主に中国メーカーによる悪質なコピー模倣品対策として、カシオはユーザーに対して模倣品排除キャンペーン -  "Don't Buy Fake" キャンペーンを行っており、QRコード/ホログラムのステッカーを使って "カシオ正規品" であることを証明できるパッケージング対策を始めている。
Casio fx-991MS の完全模倣品 OSALO OS-991MS (笑)
 Don't buy fake. (ニセモノを買うな)


購入前に正規品の確認が可能

fx-991MS
については、それまでの中国工場製造からタイ工場製造に切り替え、fx-991MS 2nd edition を投入し、パッケージにQRコードとホログラムを貼付してる。

fx-991ES PLUS 2nd edition のパッケージにも同様に QRコード/ホログラムのステッカが貼付されている。
 QR_HOlogram 

これは、購入前に店頭で正規品の確認ができるように用意されている。このQRコードを読み込むめば、正規品の確認ができ、正しいホログラムかどうかの調べ方も参照できるようになっている。
Authenticity_Check_by_QR_on_Package.png


購入後に電卓本体が正規品だと確認可能

QR_on_Calc_2fx-991ES PLUS 2nd edition は、電卓本体でQRコードと製品IDを表示する機能が追加されており、電卓本体が正規品であることを確認可能だ。
[MODE] - [0] をキーを押すとこのような表示になる。このQRコードを読み込むと正規品を証明するページにアクセスできるようになっている。

fx-991MS 2nd edition ではこの機能がないが、fx-991ES PLUS 2nd edition では模倣品対策がさらに強化されている。

電卓で表示されるQRコードを読み取ると以下のページにアクセスできる。
Authenticity_page

このページからユーザー登録すると、正規品証明書が得られる。ユーザー登録すれば、数学ゲームや漫画が楽しめる。

さらにスクロールしてゆくと、マニュアルが読める。
Manual_page

さらにスクロールしてゆくと、キャッチフレーズ "DON'T BUY FAKE PRODUCTS!" が現れる。
 DON'T_BUY_FAKE_PRODUCTS
リニューアルモデルである 2nd edition の目的はコピー模倣品排除であることがよくわかる。

 fx-991ES PLUS 2nd edition のプロモーションビデオ
このビデオでは、正規品は壊れにくく、耐久性に優れ、環境要件にも適合、使いやすく改善され、正規品のユーザー向けに容易された数学ゲームや漫画で楽しめることをアピールしている。




タイ工場での生産

fx-9750GIII_fx-991ES_2nd_edition_Integralボディ裏側にある銘板の刻印には、MADE IN THAILAND と書かれている。中国工場からタイ工場へ生産拠点を移管するのも、模倣品対策の1つと思われる。

同じく MADE IN THAILAND のスタンダード関数電卓 fx-991MS 2nd edition とボディ形状がほぼ同じで、さらにグラフ関数電卓 fx-9750GIII とは配色も含めたボディのデザインが酷似している。左が fx-9750GIII で、右が fx-991ES PLUS 2nd edition だ。



今後、地政学的観点からもカシオの製造拠点は中国からタイへの移管が進んでゆくのであろう。タイ生産拠点のスマート工場化によるコスト低減に取り組んでいる記事を紹介する。

スマート工場化で起こりうる課題、カシオがタイ工場で得たもの(前編)
スマート工場化で起こりうる課題、カシオがタイ工場で得たもの(後編)

以前購入したタイ工場製造の fx-9860GIII で、ハードカバーにあるべきゴム足が1個付いていなかった。検査工程での不良品の取りこぼしだったのだろう。品質管理のレベルが向上することを期待している。

日本国内で販売されている fx-375ES Afx-290A は、それぞれ fx-991ES PLUS 2nd editionfx-991MS 2nd edition とデザインが酷似しており、タイ工場生産品目だ。国内向けにも模倣対策品が投入され始めている。

fx-375ESA fx-290A 
   fx-375ES A        fx-290A


性能比較

fx-991ESfx-991ES PLUS 2nd edition の性能を比較してみる。

機能の比較
キー配置と各キーに割り当てられている機能は全く同じである。

計算性能の比較
分数表示と演算精度
235÷658 を計算すると 5/14 と表示され、[S↔D] キーを押せば 0.3571428571 と小数表示される。計算精度は 10 桁になっている。

桁落ち
123456789123456 - 123456789123411 を計算すると、本来 45 となるべきところ 0 となり、桁落ちが発生する。これはカシオの全ての関数電卓、グラフ関数電卓で見られるカシオ特有の問題である。ちなみに一部のモデルに搭載されている Pythonモードでは、桁落ちは見られない。

内部演算精度
radモードで tan(π/2) = -∞ となるところ、近似的に tan(355/226) として、tan( の内部実装精度、および内部演算精度を調べる。
※ tan(355/226) = -7,497,258.18532558711290507183
・fx-991ES: -7497258.44
・fx-991ES PLUS 2nd edition: -7497258.44
同じ結果になった。

べき乗とルート計算
(-32)^(3/5) を計算してみる。
・fx-991MS: Math ERROR
・fx-991MS 2nd edition: Math ERROR
fx-991ES-8
fx-991ES PLUS 2nd edition-8
・fx-JP900: -8
・fx-5800P: -8
・fx-9750GIII: -8
・fx-CG50: -8

fx-991ES の1つ前のモデル fx-991MS やリニューアルモデル fx-991MS 2nd edition では、Math ERROR となる。
一方、fx-991ES と fx-991ES PLUS 2nd edition は、両方とも正しく -8 と表示された。カシオの関数電卓では、ESシリーズで初めてこの計算を正しく行えるようになっている。
参考までに、プログラム関数電卓 fx-5800P、グラフ関数電卓 fx-9750GIIIfx-CG50 の結果も併記した。いずれも正しい結果になる。

積分計算
時間のかかる積分計算として、以下の計算を調べる。
Integral_! 
この積分は、radモードでも degモードでも同じ結果になるが、計算は rad モードで行う。

モデル結果出力処理時間
 fx-991ESπ413.4 秒
 fx-991ES PLUS 2nd editionπ400.6 秒
 fx-993ESπ411.8 秒
 fx-995ESπ427.3 秒
 fx-JP900π83.7 秒
 fx-5800Pπ173.3 秒
 fx-9750GIII (OS3.40)π14.5 秒
 fx-CG50 (OS3.50)π9.2 秒
※ 参考までに、Natural-VPAM 機能を搭載した fx-993ESfx-995ESfx-JP900、そしてプログラム関数電卓 fx-5800P、グラフ関数電卓 fx-9750GIIIfx-CG50 の結果も併記する。

fx-JP900 は極めて高速化されていて、スタンダード関数電卓の中では最速であった。fx-911ES PLUS 2nd editionfx-991ES よりも高速化されており、fx-JP900 よりも古いモデルの中では最速であった。なお、fx-993ES よりも後継モデルの fx-995ES の方が遅いのは意外であった。

fx-991ES PLUS 2nd edition は、fx-991ES と同じ機能であるが、計算速度が少し向上していることが判った。



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


 



keywords: CasioBasicプログラム電卓、fx-CG50

関連記事

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

温故知新 - CFX-9850GC PLUS

プログラム電卓 温故知新
 - 搭載プログラミング言語に注目して、プログラム電卓の変遷を考える -
<目次>


 
2019/06/23
追記修正 2020/01/04
追記修正 2021/01/11


過去から現在に至る性能や仕様の変化を調べ、プログラミング言語を中心にカシオ製プログラム電卓の系譜を明らかにする。

5. 新世代 Casio Basic 登場前夜 - 可読性と機能の向上(2)

今回は、2004年発売の CFX-9850GC PLUS を取り上げる。国内では 2005年1月に発売された。海外では2010年まで発売されていたが、国内では2006年には生産中止扱いになり、2007年にはカタログに掲載されなくなった。国内でのカタログ掲載期間は1年8ヶ月と短かった。
2005年1月発行のカシオ電卓総合カタログ
2006年9月発行のカシオ電卓総合カタログ

カシオ機に搭載されたプログラム言語で、Basicコマンドが追加されたものを欧米のプログラム電卓コミュニティでは Casio Basic と呼ばれている。私も当ブログ開設当初から Casio Basic という呼称を使っていた。

Casio BasicGetkeyLocate が追加されたのが CFX-9850G であった。その後、コマンドや関数が追加され、シリーズ最終の CFX-9850GC PLUS が登場した。この機種の後継として fx-9860G が発売され、これ以降の機種に搭載された言語を当ブログでは "次世代Casio Basic" と呼称している。

fx-9860G の1つ前の機種である CFX-9850GC PLUS はCFXシリーズの最終形であり、新世代Casio Basic 登場前夜と言える。


Casio CFX-9850GC PLUS

CFX-9850GC_PLUSCFX-9850GC_PLUS_Manual

2004年海外で発売、2005年1月 に国内発売開始、海外では2004年発売。
カタログ 取扱説明書 (Casioサイト) 取扱説明書 (e=Gadgetサイト) 

64KBのメモリ領域にシステムも含まれており、それ以外がプログラムやデータに使える。取扱説明書の表紙から分かるのは、fx-9750G PLUS(モノクロ液晶)など複数の機種とほぼ共通の仕様になっている。

取扱説明書で分からない Casio Basic の使いこなし が当ブログのメインテーマなので、実際に触ってみたいと思い、以前から中古品を探していた。


実際に入手した CFX-9850GC PLUS
幸運なことに、eBayで "未使用品 - 動作確認のため開封" というものを見つけたので入手した。EU域内保証書が添付されていた。
 CFX-9860GC_PLUS_1 CFX-9850GC_PLUS_2 
実際に傷や汚れが一切なく、新品状態であった。

CFXシリーズは、3色カラー液晶搭載のグラフ関数電卓で、デフォルトがブルーで、オレンジとグリーンを追加した3色が使える。実際の画面は、輝度も色もコントラストが低い。液晶を見る角度でコントラストや色合いが大きく変化するのも見づらさの原因だ。明るいところでは問題ないが、少し暗くなると見づらいと感じる。実際にしばらく使い続けると多少は慣れた。
CFX-9850GC_PLUS_Display 

fx-9860GIIシリーズのメニュー画面を比較する。
CFX-9850GC_PLUS_Display fx-9860GII_SD_Display 
液晶のバックグランドが黄色みが強いことも視認性の悪さの原因だと感じる。
また、この3色カラー液晶は応答性が悪い。

なお、CFX-9850GC PLUSの液晶画面のサイズは、fx-9860Gシリーズと比較すると小さいことが分かる。
Disp_Size_9859GC_9860GII 


関数電卓としての性能 [2019/06/25 追記]
キーの種類と配置は、後継機のfx-9860Gシリーズと同じになっている。但し、[SHIFT] と一緒に押して選ぶ裏の機能やファンクションメニューの機能は fx-9860G よりは少なく、当然ながら後継機で進化しているわけだ 。

分数表示と演算精度
235÷658 を計算すると 0.3571428571 と表示される。計算精度は内部15桁で、後継機種 fx-9860Gと同じ。
ここで、[F↔D] キーを押しても 5/14 にはならない。ここは、後継機種 fx-9860Gと異なる。

複素指数関数
eπi を計算してみる。計算できれば答えは -1 になる。
Complex 
fx-9850GC PLUS では複素指数関数の計算ができず、演算エラー(Ma ERROR) になる。但し、複素数の加減乗除はできる。
後継機種の fx-9860G以降のモデルでは複素指数関数の計算に対応している。


搭載言語 (Casio Basic) の概要 [2019/8/18 追記]

追加されているBasicコマンドによりプログラムの可読性と機能が向上し、さらに GetkeyLocate が追加されているのでプログラムの自由度が向上している。さらに CFX-9850G よりも関数が追加されている。

主なコマンド
 - 入力:?→, Getkey
 - 出力:" ", , Locate
 - カラーコマンド:Orange, Green (" "とSketchコマンドにのみ有効)
 - 無条件ジャンプ:Goto / Lbl
 - 条件ジャンプ: (fx-4000P、7000G と同じ仕様)
 - カウントジャンプ:Isz, Dsz
 - 条件分岐:If / Then / Else / IfEnd
 - For ループ:For / To / Step / Next
 - Do ループ:Do / LpWhile
 - While ループ:While / WhileEnd
 - 制御コマンド:Break, Return, Stop
 - 比較演算: =,, >, <,,
 - 論理演算: And, Or, Not
 - 配列:無し
 - リスト:List (配列としても使える)
 - 行列:Mat (配列としても使える)、機能としてはまだ不完全(下記参照)
  
初期化コマンド Dim が追加されているが ClrMat が無いので、プログラム内で行列領域を削除できない。 
 - 各種関数

但し、以下の要因により可読性が損なわれている。
 - Then / Else 直後の改行:Syn ERROR になる
 - 行頭での改行 (空白行):Sys ERROR になる

 主なグラフィック コマンド
 - グラフ設定:CoordOn/CoordOff, GridOn/GridOff,
        AxesOn/AxesOff, LabelOn/LabelOff
 - 座標系設定:ViewWindow,
        Xmax/Xmin/Xscl/Xfct, XdotYmax/Ymin/Yscl/
Yfct  Xdotが追加されている
 - 消去コマンド:ClrGraph, Cls
 - Sketchコマンド:Plot, PlotOn/PlotOff, PlotChg, PxlOn, PxlOff, PxlTest
          Line, F-Line, Vertical, Horizontal, Circle
 - 各種グラフコマンド

但し、Plot, PlotOn, PlotOff, PlotChg, PxlOn, PxlOff, PxlChg, Circle の詳細仕様は、後継の fx-9860G 以降とは異なる。CFX-9850GC PLUS ではこれらのコマンドのパラメータに X, Y を使うと誤動作する。X, Y は内部動作のために予約されていると思われ、これらのコマンドを実行すると予期せぬ値が X, Y に自動的に入力されてしまう。つまり、X, Y をパラメータに使ってはいけない。

後継機種である fx-9860G 以降 fx-CG50 までのグラフ関数電卓では上記のコマンド実行後に、それぞれのコマンドの詳細仕様に従った正しい値が X と Y に自動的に入力される。つまり、その詳細仕様を理解していれば上記のコマンドのパラメータに X, Y を使える。


プログラムの作成と実行
キーコード取得プログラム GETKEY を入力してみた。コマンドを入力するためのキー (キープレス) は、fx-9860Gシリーズや最新の fx-CGシリーズと全く同じだ。言語機能の基本仕様はこの機種の頃から固まっていることが分かる

ファイル名:GETKEY
Locate 1,1,"=== GET KEYCODE ==="
Locate 1,3,"KEYCODE ="
Locate 10,5,"HIT ANY KEY"
Locate 13,7,"[AC]:QUIT"
While Getkey
WhileEnd
Do
Do:Getkey→K
LpWhile K=0
Locate 9,3,"=   "
(スペース6個)
Locate 11,3,K
LpWhile 1


GETKEY 
[DEL]キーを押したところ、キーコード44が表示されている。
fx-9860Gシリーズや fx-CGシリーズと同様に、テキスト表示の範囲は21桁7行だ。

[AC]キーを押してプログラムを終了させると、画面下8行目に Break と表示される。
ここで、[EXE] を押すとプログラムが再起動し、もう一度 [AC] を押すとProgram List に戻らず RUNモードに切り替わる。
この仕様は、fx-9860Gシリーズや fx-CGシリーズとは異なる。完成したプログラムを繰り返し使うには便利な仕様だ。一方、プログラムを試してから修正する場合は面倒だ。RUNモードに戻った後、[MENU] を押して PRGMモードに移行して編集するプログラムを探す必要がある。

Program List には、プログラム名 (ファイル名) は入力した順序で並んでおり、アルファベット順になっていない。プログラムの数が多いと、編集あるいは実行したいプログラムを探すのが楽ではない。

CFX-9850GC PLUSProgram List でプログラムを探す最善の方法は、サーチ(検索)機能だ。Program List 画面で [F6] (▷) - [F1] (SRC) と押せば Search For Program 画面が現れるので、そこで探しているプログラム名の頭のアルファベットを押せば良い。すると同じ頭文字で始まるプログラム名が全て表示される。この機能は必須だ。

ところで、取扱説明書には、以下の記述がある。
Program_Manual_Note
繰り返し計算や複雑な計算を便利に実行するのが、プログラム機能の主目的だと考えれば、プログラム終了後に Program List 画面に戻らず、RUMモードになる仕様は、理にかなっている。


プログラムの編集 [2019/07/01 修正]
プログラム編集画面は、極めて使いにくい。

パソコンで文章を書く時は、通常は挿入モードで利用しているはずで、上書きモードは必要な時のみ切り替えて使うと思う。fx-9860Gシリーズや fx-CGシリーズでも、プログラム編集画面は常に挿入モードになっていて、必要な時に [SHIFT]-[DELL](INS) と押して上書きモードに切り替えて使う。

ところが、CFX-9850GC PLUS は、通常が上書きモードになっていて、[SHIFT]-[DELL](INS) を押して挿入モードに切り替える必要がある。一旦挿入モードに切り替えると、改行を超えない範囲でカーソル移動する限りは挿入モードが維持されるが、カーソルが改行を超えると上書きモードに戻ってしまう。改行から改行までを1行として認識し、その行内なら挿入モードが維持されるのは、ラインエディタの仕様をそのままマルチラインのエディタに持ち込んでると考えるのが妥当であろう。そのためマルチラインエディタとして編集の利便性が得られず残念な仕様と言える。

昔のプログラム電卓やポケコンで、区切り文字を使ってプログラムをズラズラと1行に書く時の仕様を、そのまま引きずっているのではないかと想像している。


プログラムの転送 [2019/08/15 追記修正]

PClink_9850GC_Plus2 PCリンク
3pin-USBケーブル (SB-88) と プログラムリンク ソフトウェア (FA-124) を使えばPCリンクや電卓の画面取得が可能になる。
3pin-USBケーブル (SB-88)
現在は製造中止品だが、takumako様により互換ケーブルが有償頒布されているので私はこれを利用した。
プログラムリンク ソフトウェア (FA-124)
カシオのサイトから無償ダウンロードできる。

 電卓間転送
3pin-3pinケーブル (SB-62) を使えば、3pin端子のあるグラフ関数電卓とプログラムの転送ができる。
3pin-3pinケーブル (SB-62)
まだ販売されているが、takumako様により互換ケーブルが有償頒布されている。SB-62 は fx-9860Gシリーズや fx-CGシリーズの国内正規版には標準添付されている。

PCへ転送されるファイルは CAT ファイル (拡張子 cat) だ。CATファイルには複数プログラムを格納できる。
具体的な操作方法は FA-124 のマニュアルを参照のこと。

ところで、電卓本体右下にある3pinコネクタには、防塵防滴用と思われるゴム製の "栓" が刺さっている。ある程度使われた中古品だとこれが無くなっているケースが多いのではないかと思う。無くしやすいので要注意だ。


fx-9860Gシリーズからのプログラムの移植
以前作ったプログラムの入った fx-9860Gシリーズと CFX-9850GC PLUS を 3pinケーブル (SB-62) で接続し、プログラムを CFX-9850GC PLUS に転送する。次にプログラムを走らせ、エラーが出たら [◀] か [▶] キーを押すとエラーが発生したコマンドにカーソルが表示されている。そこでカーソルのある部分を修正できるので、移植作業は比較的楽だ。当然エラーが発生している原因と対策を知っておく必要がある。具体的には、以下で紹介しているので、参照ください。

テキストベース・プログラム
モグラ叩きゲーム
以前作ったアクションゲーム - "Whack-a-Mole(もぐら叩き)" を転送して、必要な変更を行ってから遊んでみた。ついでにトップ画面のタイトルをオレンジにしてみた。デフォルトはブルーになっている。
ここで転送して修正したプログラムファイルは、WHACKAMOWAMINPI の3つだ。
プログラムのダウンロード - ダウンロードした Whackamo.cat には上記3つのプログラムを含む
Whack-a-Mole_9850GC 

CFX-9850GC PLUS の処理速度に対応するために、WHACKAMO の冒頭にある変数A の初期化を 2→A と変更しただけで、ロジックは変えていない。他は CFX-9850GC PLUS の搭載言語の制限に合わせて、エラーが出なくなるように修正を行うだけで移植は完了する。搭載言語のこの制限と修正方法については後述する。

実際に遊んでみると、液晶のハードウェアとしての応答性が悪い割にはゲームとして遊べて、それほど悪い感じはしない。表示が始まってところで反応できるから、表示が完了するまでのタイムラグが問題にならないのだろうと思う。

キーコード取得プログラム
以前作ったキーコード取得プログラムを転送し、エラーが出なくなるように必要な修正を行って CFX-9850GC PLUS / fx-9750G 専用に変更した。
プログラムのダウンロード - Keycode.cat
GetKey_1 GetKey_2 
左:起動直後の画面、右:キーコード取得プログラム、[EXIT] キーを押してみたところ。

CFX-9850GC PLUSfx-9860Gシリーズ / fx-CG シリーズは、全く同じキーを備えており、キーコードも同一になっている。従って、CFX-9850GC PLUS 特有の修正を行えば、ロジックや数値を変更せずに移植が可能となる。

さて、このプログラムや上のモグラ叩きゲームで、アルファベットの小文字が表示されていることにお気づきだろうか?

CFX-9850GC PLUS
 本体では、プログラム編集画面で小文字アルファベットを入力する方法が見つからない。ところが、小文字を使ったプログラムを fx-9860Gシリーズから転送したら小文字が表示されているのだ。

システムには既に小文字フォントが準備されていて、コードさえ入力されればプログラムで使えるようになっている。fx-5800P も同じ事情で、CcEditor / CcLinker を使えば 小文字アルファベットやその他フォントが使える。

温度換算プログラム
以前作った温度換算プログラムを転送し、エラーが出なくなるように必要な修正を行った。
ここで、転送・修正したプログラムファイルは、TEMPCONV と IN の2つだ。
プログラムのダウンロード - ダウンロードした TempConv.cat には TEMPCONV と IN が含まれる
TempConv 

プログラムの構造、ロジックは全く変更せず、プログラムが正常に動作する。

和暦-西暦換算・年齢推定プログラム - あの人の歳は今いくつ?
以前作った 和暦-西暦換算・年齢推定プログラムを転送して、エラーを解消する変更を実施した。長押し判定のカウンタの初期値Lを実機の処理速度に合わせて30に変更した (プログラム冒頭に 30→L と変更)。
転送・修正したプログラムファイルは、YEARCONV、YRC、YRD、INPI の4つだ。
プログラムのダウンロード - ダウンロードした YearConv.cat には YEARCONV, YRC, YRD, INPI の4つが含まれる。
YearConv 

ある程度複雑な構造でも、CFX-9850CG PLUS 搭載言語の制限や欠点を理解すれば、移植できることが分かった。


CFX-9850GC PLUS でのプログラミング

プログラミング上の制限と注意点 - fx-9860Gシリーズ / fx-CGシリーズとの比較

空行 (改行のみの行) はSyn ERROR になる
 ※対策空行を削除する
 対策を実施すると、ソースコードが非常に見づらくなる。特にブロック構造を意識した分かりやすいプログラミングには困った仕様だ。幸いコメントアウト ' が使えるので、空行の代わりに
'== 
などと書けば良いが、ソースレベルでブロック構造を分かりやすく見るには空行はとても便利だ。それが出来ないのは発展途上の欠点だと敢えて申し上げたい。これは、昔の1行プログラミングの時代の影響を引きすっていると感じられる。

Then / Else の直後を改行すると Syn ERROR になる
 ※対策Then / Else 直後の改行を削除する
 対策を実施すると、ソースコードが見づらくなる。上の空行禁止を組み合わさると、If ステートメントが非常に分かりにくくなる。ソースレベルで、ブロック構造を意識した見やすいコードを書けないにのは困った仕様だ。
これも、昔の1行プログラミングの影響をまだ引きずっている結果だと感じられる。

ループ (While / Do) の2重構造で、内側のループと If の入れ子構造が共存すると IfEnd のところで Syn ERROR になる
 ※対策:外側のWhile / DoLbl / Goto に置き換える。Break が有れば新たに Goto ジャンプに置き換える
 対策を施すと、スパゲティ化の第一歩となり、分かりやすいブロック構造を意識したプログラミングの大敵だ。個人的には最大の問題と感じている。
このエラーは、上記の 温度換算プログラムと和暦・西暦換算・年齢推定プログラムをfx-9860GII から転送して発見した。
While / DoIf の構造制御のスタック管理に失敗しているバグと考えている。昔は Goto / Lbl しか無かったところに構造制御ステートメントを追加している過渡期に潜り込んだバグがまだ解消していないのだろう。
取扱説明書の第22章ライブラリー編に掲載されているサンプルプログラムでは、構造制御に While / Do を使ったものが無く、全て Lbl / Goto が使われていることから、この時点で While / Do の機能が不完全だったと考えている。 

出力 "" で内部カーソルが改行されない
 ※対策"" で内部カーソルの改行機能を当てにせず Locate で表示位置を明示的に指定する
"" はNOP (何もしない) 処理になっているかも知れない。
"" で内部カーソル行を制御しているプログラム (fx-5800Pfx-9860G 以降のグラフ関数電卓で正常動作しているもの) を転送した場合、CFX-9850GC PLUS では画面配置が崩れる。

行末に区切り文字 : があると Syn ERROR になる
 ※対策:行末の区切り文字 : を削除する
 対策を実施しても大きな問題はない。
区切り文字は改行と同じ内部実装になっていれば、空行でエラーになるのと同じ原因なのだろう。

カラーコマンドは " " 出力には有効だが、Locate 出力には無効 [2019/05/25 追記]
 ※対策:有効な対策はない。"" で内部カーソルが改行されないので Locate を " "出力に変更できないことが多いためだ。
 カラーコマンドには、Orange と Green がある。Orange "String" と書けば String がオレンジ色で表示される。
一方、Locate コマンドで出力する場合は、カラーコマンドを追加すると Syn ERRORになる。 

出力文字列に : を含む行を ' でコメントアウトすると Syn ERRORになる
 ※対策:機切り文字 : の直後に ' を付加する
この問題は、fx-9860Gシリーズや fx-CGシリーズにも残っており、カシオは操作マニュアルを修正して対応している。
詳しくは 楽屋裏 - Casio Basic コメントアウト '  のバグ を参照

出力文字列に : を含んでも Syn ERRORにならない
これは、後継機種の fx-9860Gの OS2.1 かそれ以前のバージョンではエラーになっており、OS2.04 以降で修正されており、この修正は fx-9860GIIfx-CG20、そして最新の fx-CG50 まで維持されている。それなのに fx-9860G よりも古い CFX-9850GC PLUS で同じエラーが発生するかと思えば、エラーにならないのは、面白い。
改行のみの空行や区切り文字が行末にあることを許すように変更した際に、新たにバグが入り込んだと推測される。細かいようではあるが、このような開発の苦労や経緯が透けてくるのは面白い。 

出力命令 " " では1文字ごとに出力する
"Strings" を実行するとタイプライターのように1左から1文字づつ出力される。一方 Locate 1,1,"Strings" を実行すると、文字列が一度に出力される。

fx-9860Gシリーズ以降の機種からの移植では、実装されていない関数やコマンドで Syn ERROR
 ※対策:使えるコマンドを使って別表現に変更する (当たり前ですね)
今回移植を試みたプログラムには一例として、RanInt#( があったので、それぞれ以下のように別表現にした。 
- RanInt#(1,9)Int(90Ran#÷10)+1 に変更
- RanInt#(1,3)Int(30Ran#÷10)+1 に変更
- RanInt#(0,9)Int(10Ran#) に変更

Do / While / For ループからの脱出に Dsz / Isz を使うと Syn ERROR になる [2019/06/30 追記]
 ※対策:ループを Lbl / Goto に置き換えるか、ループ脱出に Break を使う
この現象は、fx-5800Pfx-9860G 以降のグラフ関数電卓でも存在することが確認されている。
⇒ 楽屋裏 - Dsz にとるループ脱出 参照
カシオとのやりとりの結果、ループの後 (必ずしも直後でなくても良い) に Goto 0:Lbl 0 と記述することでこのエラーを回避できることが分かっている (詳細は上記記事参照)。ところが、CFX-9850GC PLUS では、この対処方法が効かない。


処理速度の比較

四則演算および関数計算

加算プログラム
加算 

プログラムを起動し、N に 1000 を入力して実行時間を計る。

CFX-9850GC PLUS のプログラム
fx7000G_source_adding_up_Isz2 AddTest_For 
繰り返しに Goto / Lbl を使うケース(左)と For を使うケース(右)の2通りで処理速度を調べる。


数値積分プログラム
関数 

この通史積分は、とね日記 - 席初の手帳型プログラム関数電卓 CASIO FX-502P (1979), FX602P (1981) で取り上げられているものをそのまま使わせていただく。

プログラム起動し、分割数として 1000 を入力して、時効時間を計る。

CFX-9850GC PLUS のプログラム
FuncTest_Goto_9850 FuncTest_For_985 
クリア絵師に Goto / Lbl を使うケース(左)と For を使うケース(右)の2通りで処理速度を調べる。

以前調べた結果と併せて、上記の計算速度のを比較結果を示す [2019/07/31 修正]
加算プログラム数値積分プログラム
機種実行時間比較実行時間 (秒)比較
FX-502P123.1 秒---1261.8 秒---
FX-602P111.2 秒1.1 倍716.5 秒1.8 倍
FX-603P37.8 秒3.3 倍166.2 秒7.6 倍
fx-4000P61.7 秒2.0 倍349.1秒3.6 倍
fx-4500P195.0 秒0.6 倍798.1 秒1.6 倍
fx-4800PA=A+126.3 秒4.7 倍114.3 秒11.0 倍
Isz A21.2. 秒5.8 倍109.4 秒11.5 秒 
fx-7000GA=A+120.7 秒5.9 倍146.1 秒8.6 倍
Isz A19.3 秒6.4 倍143.2 秒8.8 倍
CFX-9850GGoto20.9 秒5.9 倍98.3 秒12.8  倍
For9.2 秒13.4 倍84.3 秒15.0 倍
CFX-9850GC PLUS
Goto22.0 秒5.6 倍100 秒12.6 倍
For9.2 秒13.4 倍85.4秒14.8 倍
記念すべき FX-502P を基準に、速度が何倍になっているかも併せて示している。

Basicコマンドとして追加された For 文は効率化、高速化している。Basicコマンドは可読性向上だけでは無いことが分かる。併せて関数処理も高速化していることが分かる。但し、CFXシリーズ初号機である CFX-9850G よりは少し遅くなっている。インタープリター言語なので、コマンドが追加されたことが原因だと思われる。


グラフィックス描画
▶ ドット描画プログラム

fx-7000G のグラフィック画面が 95 x 63 ドットなので、それに合わせて CFX-9850GC PLUS でも 95 x 63 ドットを塗りつぶして処理速度を比較する。

fx-7000G のプログラム
fx7000G_Dot DOT_fx7000G  

CFX-9850GC PLUS のプログラム
Dot_Plot Dot_Pxl fx9850GC_Plus_Dot 
Plot を使うケース(左)と PxlOn を使うケースの2通りで処理速度を調べる。

PlotPxlOn
fx-7000G213 秒
CFX-9850G926.5 秒0.23 倍496.0 秒0.43 倍
CFX-9850GC PLUS901.1 秒0.24 倍929.1 秒0.23 倍

CFX-9850G と全く同じコードであるにも関わらず、CFX-9850GC PLUS では遅くなっている。
PxlOn によるドット描画は、CFX-9850G の2倍の時間がかかった。
fx-7000G と比べると、処理が4倍以上遅くなった。


画面更新プログラム
上で、画面へのデータ転送が処理速度のボトルネックになることが分かったので、頻繁に画面更新するプログラムを実行して、その処理速度を調べて比較することにする。

ところで Getkey コマンドの追加によりテンキーと[EXE]キーだけでなく、[AC]を除く全てのキー入力が検知可能になり、Locate コマンドの追加により任意の位置への出力が可能になったので、プログラムの自由度が大きく向上し、画面がスクロールしないプログラムを書けるようになった。画面がスクロールしないプログラムでは、画面更新速度は重要な評価ポイントになる。

出力画面は、テキスト画面とグラフィックス画面 (グラフ画面) の2つがあり、これらは同時に表示できない。そこでテキスト画面の高速更新プログラムとグラフィックス画面の高速更新プログラムを作成して評価に利用することにする。

CFX-9850GC PLUS で調べる。
以下は CFX-9850G の結果で、CFX-9850GC PLUS のデータを後日追加する。

グラフィックス画面更新プログラム - モンテカルロ法にょる円周率計算
fx9850GCplus_Montekar 
プログラムのダウンロード - Montecar.cat を電卓に転送する
プログラムの詳細はこちら
ランダムに500回点を打って出力するまでの時間を調べる。

テキスト画面更新プログラム - ピタゴラス数の計算
CFX9860GCplus_Pytha 
プログラムのダウンロード - Pytha.cat を電卓に転送する
プログラムの詳細はこちら
ピタゴラス数500個を計算して結果を出力するまでの時間を調べる。

[2020/01/04 追記]
GetkeyLocate が初めて搭載された CFX-9850GCFX-9850GC PLUS の結果を比較した。
MONTECARPYTHA
CFX-9850G294.3 秒---165.6 秒---
CFX-9850GC PLUS295.2 秒0.99 倍267.7 秒0.62 倍

CFX-9850G に比べてグラフィック画面出力 (MONTECAR) と テキスト画面出力 (PYTHA) ともに遅くなった。
特に、テキスト画面への繰り返し出力は60%程度に速度低下している。関数やコマンドが追加されたので、当然ながら処理が遅くなったと言える。速度向上には、CPUやOSの大きな改訂が必要であり、次の機種である fx-0860G でそれが実現されている。


プログラム電卓の系譜 [2019/08/15 追記修正]

CFXシリーズの最終機種である CFX-9850GC PLUS は、CFX-シリーズの初号機 CFX-9850G と同じ仕様の言語を搭載しているが、処理速度が遅くなっている。CFX-9850G よりも関数や機能が増強されているので多少処理が遅くなるだろうと思う。しかしグラフィックスのドット描画については、特に PxlOn の処理が倍程度遅くなっているのは意外であった、

さて、CFX-9850GC PLUS に搭載されたプログラミング言語は、CFX-9850G と同様に Baiscコマンドとして IfFor / While / Do / Getkey / Locate などが追加されているが、編集画面で考えながらコーディングするのは難しいと思う。

後継機種である fx-9860G では、搭載言語と編集画面の大幅な修正が行われた。この改良は、fx-9860G と同年に発売された fx-5800P にも反映されている。

編集画面については、FX-502P / FX-602P / FX-603P では、デフォルトで挿入モードになっており、必要に応じて 上書きモードに切り替える仕様になっている。ところが、その後の fx-3650Pfx-4000P シリーズ、fx-7000G シリーズ そして CFXシリーズの最終モデル CFX-9850GC PLUS に至るまで、デフォルトで上書きモードになっていた。

当時、欧米市場での競合であった TI の電卓でも84シリーズのような古くからある機種では上書きモードが主流であった (sentaro様による情報、コメント欄参照)。

ところが、2005年に発売された機種、fx-71Ffx-5800Pfx-9860G では、一斉に挿入モードに切り替わっている。プログラミングのできない関数電卓においても、fx-991MS まではデフォルトで上書きモードで、2005年発売の次機種 fx-991ES から挿入モードに切り替わっている (2005年1月の電卓総合カタログ参照。

[2019/07/01 追記]
コメント欄に情報をお寄せいただいたsentaro様によれば、SHARP製の関数電卓も以前は上書きモードだったが、2004年以降のモデルは挿入モードに変わっているとのこと。Casioとほぼ同時期に変更されているようだ。

sentaro様の考察によれば(コメント欄参照)、欧米、特に北米での学校販売ビジネスでしのぎを削っていた TI 機と使い勝手の異なる挿入モード機を一斉に投入するには、ビジネス上のリスクを伴う大きな判断があったに違いないとのことだ。私もそれに賛同する。その上で、一斉に挿入モードに切り替えたのは、グラフ関数電卓やプログラム関数電卓の将来の目標 / ビジョンがあったのではないかと私は想像している。それは計算補助のマクロ機能を超えて、より柔軟な一般的なプログラミングが可能な言語仕様を目指すことであった、と想像している。

LocateGetley コマンドの存在は、スクロールしないプログラムを可能にするが、これらのコマンドは CFXシリーズの初代 CFX-9860G に初めて追加された。CFXシリーズは、プログラム関数電卓、ポケコン、グラフ関数電卓それぞれで個別に開発が進んでいた搭載言語が、ようやく1つの方向性に収束し、Locate / Getkey コマンドを追加することで柔軟なプログラミングが可能になり、大きく進化した。3色限定とは言えカラー表示を可能にしたのも CFXシリーズの特徴であり、各種コマンドや関数を増強した最終機種 CFX-9850GC PLUS は、カシオ機搭載のプログラミング言語の歴史の重要な転換点を示しており、次世代Casio  Basic 登場前夜の記念すべきモデルと言える。

Casio Baisc は fx-9860G シリーズでさらに進化してゆく。



温故知新 - FX-502P / FX-602P / FX-603P
温故知新 - fx-4000P / fx-4500P / fx-4800P
温故知新 - fx-7000G
温故知新 - CFX-9850G
温故知新 - CFX-9850GC PLUS

温故知新 - fx-9860G
温故知新 - fx-5800P
温故知新 - fx-9860GII
温故知新 - fx-CG20
温故知新 - fx-CG50
温故知新 - fx-CP400
温故知新:番外編 - 関数電卓としての使い勝手



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


 


keywords: プログラム関数電卓、プログラミング、Casio Basic、CFX-9850GC PLUS

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













関連記事

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

温故知新 - fx-9860G

プログラム電卓 温故知新
 - 搭載プログラミング言語に注目して、プログラム電卓の変遷を考える - 
<目次>


 
2020/01/04
追記 2020/01/09

過去から現在に至る性能や仕様の変化を調べ、プログラミング言語を中心にカシオ製プログラム電卓の系譜を明らかにする。

6. 新世代 Casio Basic の登場 - プログラム機能の大幅な向上

今回は、CFX-9850GC PLUS の後継機として海外で2005年発売の fx-9860G を取り上げる。国内では、fx-5800P が先に発売され(2006年9月)、その後に fx-9860G が発売されている (2006年10月以降)。国内と海外で発売時期が異なるのは珍しいことではない。
2006年9月発行のカシオ電卓総合カタログ
2007年12月発行のカシオ電卓総合カタログ

カシオ機に搭載されたプログラム言語に初めて GetkeyLocate が追加され、画面スクロール無しで入出力ができるようになったのが CFX-9850G であった。これに関数やコマンド類が追加され、このシリーズ最終モデルが CFX-9850GC PLUS であったが、プログラミング言語としては色々な癖があり、使い易いとは言えなかった。

CFX-9850GC PLUS の後継機種として、その言語仕様ならびにエディタ画面が大幅に改善された fx-9860G が今回取り上げるモデルで、これには 新世代Casio Basic と言うべき言語が搭載されていた。

[2020/01/07 追記]
2005年に発売されてから、fx-9860G の基本設計はそのまま新機種 (例えば、2020年での fx-CG50) に引き継がれてているのは、このモデルの設計がどれだけ野心的であったか、そしてその完成度の高さを示している。


Casio fx-9860G

fx-9860G_Calc
fx-9860G が、欧米で2005年に発売され、国内では 2006年10月以降(おそらく2007年?)に発売された。

カタログ 取扱説明書 (e-Gadgetサイト) 

CPUは、日立製SH3のカスタムチップ SH7705を使っている。

メインメモリは 63KBで、Casio Basicを含めたOSが格納されている。

fx-9860G
の最大の特徴の1つはアドインプログラムが使えるようになったことで、1.5MBもの(当時としては広大な)ストレージメモリ(保存メモリ)を備えており、アドインプログラムを保存し走らせることが出来る。なお、アドインプログラム作成用のSDKも公開された。SDKの入手

なお、オーストラリア版の fx-9860G AU は、理由が不明だがストレージメモリが 0.8MB と少ない。

液晶周りの光沢コーティングや筐体裏側のつや消し黒塗装は高級感を演出していて、個人的には好きなデザインだ。

OSの変遷
2005年の発売当初のOSバージョンは 1.02、その後 1.03、1.04、1.05 とアップデートファイルが提供された。
2009年に fx-9860GII (SH3, OS2.00) が発売されると、機能を近づけた(実は完全に同じにならなかった) fx-9860G 用の OS2.00 へのアップデートファイルが公開され、その後 OS2.01 へのアップデートファイルが提供された。

OS 1.02 と 1.03 では Casio Basicの処理速度には大きな違いがなく、一連のバージョンの中で最速であった。OSがアップデートするにつれCasio Basicのデバッグと機能追加が進むが、一方で処理速度は遅くなる傾向は確実にある。実際にベンチマークを行った結果は以下に示す。

電源の変更
1つ前の機種 CFX-9850GC PLUS までは、駆動用電池に加えてバップアップ用電池を使っていた。fx-9860G も初期はバックアップ用のコイン型リチウム電池CR2032を用いていたが、そのうちバックアップ電池を使わずに単四電池4本のみでバックアップ機能を実現するようにマイナーアップデートされた。

fx-9860G_Battery_Case2 
左は コイン型リチウム電池 CR2032 を使うモデル、右は 単四4本のみでバックアップ機能のあるもの。バックアップ電池用の樹脂型が修正され、その跡が見てとれるのが興味深い。この電源周りのバージョンアップは特にアナウンスされないままマイナーバージョンアップされたようだ。

関数電卓としての性能

分数表示と演算精度
235÷658 を計算すると 0.3571428571 と表示される。ここで、[F↔D]キーを押すと 5/14  と表示される。計算精度は内部15桁だ。

複素指数関数
eπi を計算してみる。計算できれば答えは -1 になる。
1つ前の機種 fx-9850GC PLUS では複素指数関数の計算ができず、演算エラー(Ma ERROR) になったが、fx-9860G で初めて複素指数関数の計算に対応した。

一方、e(5/3)πi を計算させると、0.5 - 0.8660254038i と表示され、[F↔D]キーを押すと 1/2 - 0.8660254038i  と表示される (OSバージョンによらない)。なお、次の機種 fx-9860GII 以降は自然数式表示機能が徹底され、これを計算すると 1/2 - √3/2i と表示される。

積分計算 [2021/01/09 追記]
時間のかかる積分計算として以下の計算を調べる。
Integral_! 

モデル名 (OSバージョン)結果出力処理時間
fx-9860G Slim (OS2.00)3.14159265421.5 秒
fx-9860G (OS2.01)3.14159265422.3 秒
fx-9860G Slim (OS1.11)3.14159265423.6 秒
fx-9860G (OS1.03)3.14159265426.2 秒

fx-9860Gシリーズは、最初の出力が分数になり、[F↔D] キーを押すと π と表示される。
OSバージョンが 1.xx から 2.xx に変わると積分計算が速くなる。
同じOSバージョンでも、fx-9860G よりも fx-9860G Slim の方が速い。
 

搭載言語 (Casio Basic) の概要

fx-9860G OS1.0x では、CFX-9850GC PLUS の搭載コマンドと同一である。その後 OS2.01 では 次機種の fx-9860GII で追加された文字列処理や細かなコマンドと同じものが追加された。

主なコマンド (OS1.0x) [2020/01/07 修正 ※]
 - 入力:?→, Getkey
 - 出力:" ", , Locate
 - テキスト画面消去:ClrText
 - 無条件ジャンプ:Goto / Lbl
 - 条件ジャンプ: (fx-4000P、7000G と同じ仕様)
 - カウントジャンプ:Isz, Dsz
 - 条件分岐:If / Then / Else / IfEnd
 - For ループ:For / To / Step / Next
 - Do ループ:Do / LpWhile
 - While ループ:While / WhileEnd
 - 制御コマンド:Break, Return, Stop
 - 比較演算: =,, >, <,,
 - 論理演算: And, Or, Not
 - 配列:無し
 - リスト:List (配列としても使える)
  ※但し、x→Dim List 1 の初期化ができず、{1,2,3,4,5}→List 1 とする必要がある
  ※一方で、ClrList は正常動作する

 - 行列:Mat (配列としても使える)

  ※ {m,n}→Dim Mat A で初期化できず、ClirMat がないので行列機能はまだ不十分
 - 各種関数

1つ前の機種 CFX-9850GC PLUS の以下の問題は解消されている;
 - Then / Else 直後の改行:Syn ERROR になる
 - 行頭での改行 (空白行):Sys ERROR になる

 主なグラフィック コマンド [OS1.0x]
 - グラフ設定:CoordOn/CoordOff, GridOn/GridOff,
        AxesOn/AxesOff, LabelOn/LabelOff
 - 座標系設定:ViewWindow,
        Xmax/Xmin/Xscl/Xfct, XdotYmax/Ymin/Yscl/
Yfct
 - 消去コマンド:ClrGraph, Cls
 - Sketchコマンド:Plot, PlotOn/PlotOff, PlotChg, PxlOn, PxlOff, PxlTest
          Line, F-Line, Vertical, Horizontal, Circle
 - 各種グラフコマンド

但し、Plot, PlotOn, PlotOff, PlotChg, PxlOn, PxlOff, PxlChg, Circle の詳細仕様は、CFX-9850GC PLUS と異なり、これらのコマンドのパラメータに X, Y を使えるが、これらのコマンドを実行すると論理座標系での X と Y の値が 変数 X と Y に自動的に入力される仕様を意識して X と Y を使う必要がある。


プログラムの作成と実行
キーコード取得プログラムを入力した。コマンドを入力するためのキー (キープレス) は、1つ前の CFX-9850GC PLUSfx-9860Gシリーズ、fx-9860GIIシリーズ、最新の fx-CGシリーズと全く同じだ。言語機能の基本仕様は1つ前の機種 (CFX-9850GC PLUS) から固まっていることが分かる

ファイル名:GETKEY
Locate 1,1,"=== Get Keycode ==="
Locate 1,3,"Keycode ="
Locate 10,5,"Hit Any Key"
Locate 13,7,"[AC]:Quit"
While Getkey
WhileEnd
Do
Do:Getkey→K
LpWhile K=0
Locate 9,3,"=   "
(スペース6個)
Locate 11,3,K
LpWhile 1


Keycode 
この画面は、[DEL]キーを押して、キーコード44が表示されているところだ。
なお、fx-9860G では アルファベットの小文字をプログラムで使えるようになった。
fx-9860GIIシリーズや fx-CGシリーズと同様に、テキスト表示の範囲は21桁、7行だ。

プログラムリスト
Program_List 
Program List には、アルファベット順にプログラム名 (ファイル名) が並んでおり、アルファベット順になっていなかった CFX-9850GC PLUS の入力順という仕様よりも大幅に使いやすく改善されている。

プログラムの編集
プログラム編集画面は、挿入モードになっており、使いやすい。

1つ前の CFX-9850GC PLUS まではプログラム編集は上書きモードになっており、極めて使いづらかった。ちなみにスタンダード関数電卓 (fx-991MSなど) も上書きモードになっていた。実は、2005年以降発売のプログラム電卓 (fx-9860G) やスタンダード関数電卓 (fx-991ES) から一斉に上書きモードに変更されている。

おもしろいことに、シャープも40周年記念モデルが発売されたほぼ同じ時期に上書きモードから挿入モードに一斉に切り替えられているようだ。余談だが、ソニー創業者の一人である井深大氏の著書(「ボスニアの夜は更けて」だったかよく覚えていないが...)で、"技術の連通管現象" ということを書かれている。世の中の技術の進歩はどこかで底通していて、そのレベルは同じように上がる、どこかだけのレベルが上がることはない、といった意味のことであり、これが思い出される。
 
パソコンで文章を書く時は、通常は挿入モードで利用しているはずで、上書きモードは必要な時のみ切り替えて使うと思う。fx-9860Gシリーズ以降のプログラム電卓では、プログラム編集画面は常に挿入モードになっていて、必要な時に [SHIFT]-[DELL](INS) と押して上書きモードに切り替えて使う。

以前のプログラム電卓やポケコンでは、区切り文字を使ってプログラムをズラズラと1行に書いていた。fx-9860G において、そのく仕様から完全に決別したと言える。


プログラムの転送
3Pin_USB_Link PCリンク : 3Pin - USB ケーブル利用
3pin-USBケーブル (SB-88) と プログラムリンク ソフトウェア (FA-124) を使えばPCリンクや電卓の画面取得が可能になる。
3pin-USBケーブル (SB-88)
現在は製造中止品だが、takumako様により互換ケーブルが有償頒布されているので私はこれを利用した。
プログラムリンク ソフトウェア (FA-124)
カシオのサイトから無償ダウンロードできる。

 電卓間転送
3pin-3pinケーブル (SB-62) を使えば、3pin端子のあるグラフ関数電卓とプログラムの転送ができる。
3pin-3pinケーブル (SB-62)
まだ販売されているが、takumako様により互換ケーブルが有償頒布されている。SB-62 は fx-9860Gシリーズや fx-CGシリーズの国内正規版には標準添付されている。

USB_USB_Link PCリンク:USB (mini) - USA (A) ケーブル利用 
fx-9860G に同梱される USB(mini)-USB(A)ケーブルを用いると、3Pin-USBケーブル利用よりも高速に転送可能だ。プログラムリンクソフトウェア (FA-124) を使えばPCリンクや電卓の画面取得が可能になる。


ところで、PCへ転送されるファイルは g1m ファイル (拡張子 g1m) だ。










テキストベース・プログラム
モグラ叩きゲーム
以前 fx-9860GII で作ったアクションゲーム - "Whack-a-Mole (もぐら叩き)" を転送した。fx-9860G の OS2.0 以上なら完全互換で動作した。ここで転送したプログラムファイルは、WHACKAMOWAMINPI の3つだ。

WAM_1 WAM_2 

fx-9860G OS1.02OS1.05 では、RanInt#( 関数が備わっていないので、RanInt#( の代わりに Int(Ran#( を使って同等に動作するように変更する必要があった。OS2.0 以上にアップデートすれば、RanInt#( 関数が追加さるので、fx-9860GII と完全互換で動作するようになる。


fx-9860G でのプログラミング

1つ前の CFX-9850GC PLUS からの改善点
CFX-9850GC PLUS のプログラミング言語 Casio Basic は数々の問題が残っていたが、fx-9860G で殆ど改善された。以下に個別の項目を列挙する。

空行 (改行のみの行) はSyn ERROR になる
 この問題は改善された。これは、昔の1行プログラミングの時代の影響が解消された。

Then / Else の直後を改行すると Syn ERROR になる
 この問題は改善された。上の空行禁止の問題の解消と併せて、If ステートメントの可読性が大いに向上した。

ループ (While / Do) の2重構造で、内側のループと If の入れ子構造が共存すると IfEnd のところで Syn ERROR になる
 この問題は改善された。このエラーは、While / DoIf の構造制御のスタック管理に失敗しているバグと考えられ、構造制御ステートメント While / Do を追加した直後に潜り込んだバグだったと思われる。 

出力 "" で内部カーソルが改行されない
 この問題は改善された。

行末に区切り文字 : があると Syn ERROR になる
 この問題は改善された。

出力文字列に : を含む行を ' でコメントアウトすると Syn ERRORになる
 ※対策:機切り文字 : の直後に ' を付加する
この問題は、fx-9860Gだけでなく、fx-9860GII や fx-CGシリーズにも残っており、カシオは操作マニュアルを修正して対応している。詳しくは 楽屋裏 - Casio Basic コメントアウト '  のバグ を参照

出力命令 " " では1文字ごとに出力する
"Strings" を実行するとタイプライターのように、左から1文字づつ出力されることは無くなった

fx-9860G OS1.0x では実装されていない関数やコマンドでの Syn ERROR
例えば、Whack-a-Mole (モグラ叩きゲーム) で使っている、RanInt#( は OS2.00 以降にはあるが、OS1.0x には無い。そこで、以下のようにすれば対抗可能だ。 
- RanInt#(1,9)Int(90Ran#÷10)+1 に変更
- RanInt#(1,3)Int(30Ran#÷10)+1 に変更
- RanInt#(0,9)Int(10Ran#) に変更

Do / While / For ループからの脱出に Dsz / Isz を使うと Syn ERROR になる
 ※対策:ループを Lbl / Goto に置き換えるか、ループ脱出に Break を使う
この現象は、fx-5800Pfx-9860G 以降のグラフ関数電卓でも存在することが確認されている。
⇒ 楽屋裏 - Dsz によるループ脱出 参照
カシオお客様サポートのご担当者とのやりとりの結果、ループの後 (必ずしも直後でなくても良い) に Goto 0:Lbl 0 と記述することでこのエラーを回避できることが分かっている (詳細は上記記事参照)。


処理速度の比較

四則演算および関数計算

加算プログラム
加算 

プログラムを起動し、N に 1000 を入力して実行時間を計る。

fx-9860G のプログラム
fx7000G_source_adding_up_Isz2 AddTest_For 
繰り返しに Goto / Lbl を使うケース(左)と For を使うケース(右)の2通りで処理速度を調べる。


数値積分プログラム
関数 

この通史積分は、とね日記 - 席初の手帳型プログラム関数電卓 CASIO FX-502P (1979), FX602P (1981) で取り上げられているものをそのまま使わせていただく。

プログラム起動し、分割数として 1000 を入力して、時効時間を計る。

fx-9860GS のプログラム
FuncTest_Goto_9850 FuncTest_For_985 
繰り返しに Goto / Lbl を使うケース(左)と For を使うケース(右)の2通りで処理速度を調べる。

以前調べた結果と併せて、上記の計算速度のを比較結果を示す [2019/07/31 修正]
加算プログラム数値積分プログラム
機種実行時間比較実行時間 (秒)比較
FX-502P123.1 秒---1261.8 秒---
FX-602P111.2 秒1.1 倍716.5 秒1.8 倍
FX-603P37.8 秒3.3 倍166.2 秒7.6 倍
fx-4000P61.7 秒2.0 倍349.1秒3.6 倍
fx-4500P195.0 秒0.6 倍798.1 秒1.6 倍

fx-4800P
A=A+126.3 秒4.7 倍114.3 秒11.0 倍
Isz A21.2. 秒5.8 倍109.4 秒 11.5 倍
fx-7000GA=A+120.7 秒5.9 倍146.1 秒8.6 倍
Isz A19.3 秒6.4 倍143.2 秒8.8 倍
CFX-9850GGoto20.9 秒5.9 倍98.3 秒12.8  倍
For9.2 秒13.4 倍84.3 秒15.0 倍
CFX-9850GC PLUSGoto22.0 秒5.6 倍100 秒12.6 倍
For9.2 秒13.4 倍85.4 秒14.8 倍

fx-9860G

OS 1.02
Goto2.1 秒61.6 倍14.6 秒86.4 倍
For1.3 秒94.7倍13.2 秒95.6 倍
OS 1.03Goto2.1 秒61.6 倍14.4 秒87.6 倍
For1.1 秒111.9 倍13.1 秒96.3 倍
OS 1.04Goto2.5 秒61.6 倍14.3 秒88.2 倍
For1.2 秒102.6 倍13.0 秒97.1 倍
OS 1.05Goto2.3 秒61.6 倍14.3 秒88.2 倍
For1.2 秒102.6 倍13.1 秒96.3 倍
OS 2.01Goto3.6 秒34.2 倍17.0 秒74.2 倍
For2.5 秒49.2 倍15.1 秒83.6 倍
記念すべき FX-502P を基準に、速度が何倍になっているかも併せて示している。

加算処理、数値積分(関数処理) は格段に高速化し、FX-502P の 100倍程度だ。Goto / Lbl ループより For の方が倍近く速い。
OSのバージョンにより、処理速度の差が顕著に表れている。OS 1.03 と OS 1.04 が最も高速だ。
次機種 fx-9860GII の登場に併せてがOS 2.01 へのアップデートファイルが提供され、使える関数が増強された。但し処理速度は遅くなった。


グラフィックス描画
▶ ドット描画プログラム

fx-7000G のグラフィック画面が 95 x 63 ドットなので、それに合わせて fx-9860G でも 95 x 63 ドットを塗りつぶして処理速度を比較する。

fx-7000G のプログラム
fx7000G_Dot DOT_fx7000G  

fx-9860G のプログラム
Dot_Plot Dot_Pxl 
Plot を使うケース(左)と PxlOn を使うケースの2通りで処理速度を調べる。

PlotPxlOn
fx-7000G213 秒
CFX-9850G926.5 秒0.23 倍496.0 秒0.43 倍
CFX-9850GC PLUS901.1 秒0.24 倍929.1 秒0.23 倍
fx-9860GOS 1.02251.2 秒0.85 倍255.7 秒0.83 倍
OS 1.03251.7 秒0.84 倍256.6 秒0.83 倍
OS 1.04252.8 秒0.84 倍257.5 秒0.83 倍
OS 1.05251.9 秒0.85 倍256.7 秒0.83 倍
OS 2.01295.8 秒0.72 倍301.7 秒0.71 倍

fx-9860G では、CFX-9850GC PLUS よりも3倍程度高速化している。
また1つ前の CFX-9850GC PLUS では、PxlOn によるドット描画は Plot の2倍程度の処理時間であったが、fx-9860G では PxlOnPlot は同等レベル、PxlOn が僅かに高速であった。

但し、fx-7000G よりは依然遅い。加算処理や関数処理は大幅に高速化しているのに、ドット描画が大変遅い理由として画面更新が大変遅いことが挙げられる。


画面更新プログラム
上で、画面へのデータ転送が処理速度のボトルネックになることが分かったので、頻繁に画面更新するプログラムを実行して、その処理速度を調べて比較することにする。

ところで Getkey コマンドが返すキーコードは、テンキーや[EXE]キーだけでなく、[AC]を除く全てのキーに対応しており、Locate コマンドで任意の位置への出力が可能なので、プログラムの自由度が大きく、画面がスクロールしないプログラムを書ける。そして画面がスクロールしないプログラムでは、画面更新速度は重要な評価ポイントになる。これが適用できるのは、CFX-9850G, CFX-9850GC PLUS そして fx-9860G なので、これらのデータを比較する。

出力画面は、テキスト画面とグラフィックス画面 (グラフ画面) の2つがあり、これらは同時に表示できない。そこでテキスト画面の高速更新プログラムとグラフィックス画面の高速更新プログラムを作成して評価に利用することにする。

グラフィックス画面更新プログラム - モンテカルロ法にょる円周率計算 - MONTECAR
Moneca_fx-9860G 
プログラムのダウンロード - Montecar.g1m を電卓に転送する
プログラムの詳細はこちら
ランダムに500回点を打って出力するまでの時間を調べる。

テキスト画面更新プログラム - ピタゴラス数の計算 - PYTHA
Pytha_fx9860G 
プログラムのダウンロード - PYTHA.g1m を電卓に転送する
プログラムの詳細はこちら
ピタゴラス数500個を計算して結果を出力するまでの時間を調べる。

MONTECARPYTHA
CFX-9850G294.3 秒165.6 秒
CFX-9850GC PLUS295.2 秒0.99 倍267.7 秒0.62 倍
fx-9860GOS 1.0276.0 秒3.87 倍115.4 秒1.44 倍
OS 1.0389.3 秒3.30 倍115.8 秒1.43 倍
OS 1.0489.4 秒3.30 倍115.8 秒1.43 倍
OS 1.0589.2 秒3.30 倍115.9 秒1.43 倍
OS 2.0195.8 秒3.07 倍128.7 秒1.29 倍

GetkeyLocate を最初に搭載した CFX-9860G を基準に、処理速度の比率も合わせて示した。

MONTECAR はグラフィック画面にドットを繰り返し描画する。fx-9860G での処理速度向上は3倍以上になった。PYTHA はテキスト画面に文字を繰り返し出力する。fx-9860G での処理速度は 1.3~1.4倍程度となった。これらの比較から、fx-9860G ではテキスト出力は多少速くなり、グラフィックス出力が大きく向上したと言える。

fx-9860G のOS が 1.0x から 2.01 にアップデートされると、明らかに画面出力が遅くなったことも併せて分かる。


プログラム電卓の系譜 

単なる計算やグラフ表示のマクロ言語から脱却し、アプリケーションとしてのプログラムを書けるように進化した 新世代Casio Basic を搭載したのが fx-9860G だ。カシオのプログラム電卓の中で極めて大きな進化を遂げたモデルであり、現行モデルの基本設計がこのモデルで固まった。

fx-9860G は、カシオのプログラム電卓で初めてアドインプログラムを走らせることができ、それを開発するための公式SDKを提供した野心的なモデルでもある。

プログラム編集モードにおいて 挿入モードがデフォルトになった点も高く評価できる。2005年発売の fx-9860G だけでなく、この年以降に発売されるプログラム電卓と関数電卓の全てがデフォルトで挿入モードに変更されているのは、カシオ電卓事業における大きな判断があったと思われる。

2005年発売の fx-9860G のハードウェア仕様、関数やコマンド類全てにおける基本設計は、2020年現在の fx-CG50 にまで引き継がれている。

fx-9860G は、新たにUSBポートを備え、PCとUSBケーブルでリンクできるようになり、従来の 3Pin - USB接続よりも高速なデータ転送が可能になった。SDカードをストレージとして使える fx-9860G SD が同時発売されたことから、データ保存とデータリンクに新たな機能を提供するモデルとなった。

さらに 2007年発売の fx-9860G Slim も重要なモデルで、クラムシェル(2つ折り)タイプで小型化しつつ液晶画面の大型化が実現した。ハンドヘルド電卓として世界初のバックライト機能も追加された。(fx-9860G Slim については別途まとめている)

fx-9860G シリーズは、ハードウェアとソフトエアの基本設計は、その後のグラフ関数電卓に色濃く引き継がれている。カシオの電卓開発史上、最重要のマイルストーンと言って良いと思う。

fx-9860G シリーズに搭載されている Casio Basic は、fx-4000Pfx-7000G の上位互換の仕様を有しており、Casio Basic の系譜は fx-9860G に引き継がれ、大きく改善され、ようやくマクロ処理ではない実用的なアプリ開発が可能な言語に仕上がった集大成が fx-9860G である。

fx-9860G の 新世代Casio Basic からグラフィクス、I/O機能と文字列処理機能が削られ、入力コマンドの改善と配列変数が追加されたサブセット版が fx-5800P に搭載され、この流れと並行して直系の改良版が fx-9860GII に引き継がれることになる。



温故知新 - FX-502P / FX-602P / FX-603P
温故知新 - fx-4000P / fx-4500P / fx-4800P
温故知新 - fx-7000G
温故知新 - CFX-9850G
温故知新 - CFX-9850GC PLUS

温故知新 - fx-9860G
温故知新 - fx-5800P
温故知新 - fx-9860GII
温故知新 - fx-CG20
温故知新 - fx-CG50
温故知新 - fx-CP400
温故知新:番外編 - 関数電卓としての使い勝手



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


 


keywords: プログラム関数電卓、プログラミング、Casio Basic、CFX-9850GC PLUS

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













関連記事

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

プログラム電卓 温故知新

プログラム電卓 温故知新
 - 搭載プログラミング言語に注目して、プログラム電卓の変遷を考える -

 
2021/01/04

特定のカシオ製プログラム電卓について、過去から現在に至る性能や仕様の変化を調べ、プログラミング言語を中心にカシオ製プログラム電卓の系譜を明らかにする。


目 次

温故知新 - FX-502P / FX-602P / FX-603P
 1. キーストローク式言語 - 携帯型プログラム電卓の普及

温故知新 - fx-4000P / fx-4500P / fx-4800P
 2. 新しいプログラミング言語の指向 - 可読性の向上

温故知新 - fx-7000G
 3. グラフ機能の追加

温故知新 - CFX-9850G
 4. Casio Basic 登場 - 可読性と機能の向上 (1)

温故知新 - CFX-9850GC PLUS
 5. 新世代 Casio Basic 登場前夜 - 可読性と機能の向上 (2)

温故知新 - fx-9860G
 6. 新世代 Casio Basic の登場 - プログラム機能の大幅な向上

温故知新 - fx-5800P
 7. 新世代 Casio Basic の特殊バージョン - 機能の改善

温故知新 - fx-9860GII
 

温故知新 - fx-CG20
  

温故知新 - fx-CG50


 

温故知新 - fx-CP400
 

温故知新:番外編 - 関数電卓としての使い勝手









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


 


keywords: プログラム関数電卓、プログラミング、Casio Basic、CFX-9850GC PLUS

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













関連記事

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

ついに fx-5800P がPCリンク可能になった

2018/02/10
更新 2021/01/04

fx-5800P と PCのデータリンクを使いこなす CcLinker


アップデート状況
  • CcLinker Dongle の頒布 ⇒ 詳しくはこちら [2019/05/08]
  • CcLinker が Ver 4.0a にアップデートダウンロードはこちら [2019/05/08]
    ※ fx-5800Pと連動して自動化され、さらにWindowsバージョンの違いによる誤動作発生が低減されました


はじめに

小型でバランスのとれた fx-5800P での Casio Basic プログラミングは、当ブログの重要テーマです。しかし致命的な問題として、カバーのヒンジが壊れやすいこと、そしてPCとのデータリンクができない点が挙げられる。これについては "fx-5800P プログラムのバックアップ" で取り上げている。

本来カシオが提供すべきものだと思うのだが、fx-5800P 発売から10年以上経ても、カシオ自身やサードパーティからまだ提供されていなかったが、ついに待ち望んだPCとのデータリンクが実現した

以前から、fx-5800P のデータリンクが検討されてきた。当ブログにおいても、"fx-5800P プログラムのバックアップ" の記事に kikkawa様や AkSd様のコメントで、データ解析ができて、なんとかなるかも知れないというコメントを頂いていた。そして、AkSd様の 関数電卓ファン掲示板 で様々な情報交換がなされ、応援コメントなども集まるようになった。

その中で、takumako様 が CcLinker というデータリンクツールを完成なさった。

takumako様の CcLinkerホームページ

現在は、ファームウェア書き込み済みの以下のような形態で頒布なさっている。
 CcLinkerDongle 

購入方法の詳細は、CcLinker Dongle の頒布 を参照のこと。


CcEditor の紹介

CcLinker で転送したプログラムファイル (CCLファイル) を CcEditor というプログラミングアプリで編集・作成すると fx-5800P の隠し機能が使えてプログラミングの幅が広がる。また、ソースコードにインデントが付けられたり、Getkey のキーコードが簡単に入力できたりと、CcEditor は fx-5800P 専用の優れたプログラミングツールだ。 CcLinker と合わせて CcEditor を使う価値は十分ある。

[2019/05/08 追記]
CcEditor は Ver 2.2 にアップデートされ、さらに使い勝手が改善されている。
CcEditor の簡単な紹介


CcLinker Dongle の導入

NewUSBDongle実際に CcLinker Dongle を入手して使ってみた。左の写真は私が入手した最新のものだ。

[2018/08/07 追記]
できるだけ多くの方に使って頂きたいという作者のtakumako様のお考えから、期間限定を無くして、いつでも有償頒布を受け付けるとのこと。とてもありがたい話だ。

fx-5800P をPCとリンクするには、写真の USBドングルとWindows デスクトップアプリを使う。


実際にWindows 10 で使ってみたので、以下に紹介する。


デバイスドライバーのインストール

先にUSBドングルをPCに奥まできちんと刺し、添付の Windowsデスクトップアプリ - CcLinker を起動すると、自動的にデバイスドライバのインスト-ルが始まる。Windows 10 では、右下にインストールが終了した旨のメッセージが現れる。但し、Windowsアプリのウィンドウは表示されない。

一旦デバイスドライバがインストールされた後 CcLinker アプリを起動するとアプリウィンドウが表示される。


PC保護の警告

Ver 1.6d 以前の CcLinker を初めて起動するとき、Windowsの保護機能が発動してしまう。

PC_Protection.PNG 

自作プログラムでは、最初は間違い無くこれが表示される。CcLinker も危険ではないのに大きなお世話である。気をつけるべきはダウンロード先は作者のオリジナルサイトを使うことだ。おそらく Microsoft がユーザーのPCからインストールプログラムを監視し、そのデータを抽出し、多数決方式でインストール数が少なければ一旦待ったをかける機能だろうと思われる。

ここで、詳細情報 をクリックしたら現れる [実行]をクリックし、アプリを実行すれば次回からこの警告は現れない。
自作プログラムがPC保護機能に引っかかる

[2018/07/31 追記]
CcLinker Ver 1.6e 以降は、この問題を回避するために フリーの圧縮解凍アプリ CGA にて圧縮されたファイル(拡張子がCGA)でも供されている(詳しくはコチラを参照)。

[2019/05/08 追記]
CcLinker Ver 4.0a は zipファイルでの提供もされている。古いバージョンからのアップデートなら zipファイルを入手上書きすれば良く、PC保護機能に引っかかることはない。


CcLinker の起動

最初に USBドングルとfx-5800Pを接続した後、USBドングルをPCに刺す (確実に接続する方法)。
その後 Windowsアプリ CcLinker を起動する。無事に起動すると、CcLinker のウィンドウが表示される。

Pclink_fx-5800P   CcLinkerV4_Booted 

CcLinker Ver 2.0b 以降は [Transmit] ボタンと [Receive] ボタンが廃止され、fx-5800P 上で Transmit や Receive を選択した時に CcLinkerが自動的に連動するようになった。Ver 2.1a で画面の背景に薄い色が付き、見やすくなった。 

もし、ドングルを刺さずに アプリを起動すると、エラーメッセージが表示される。

Boot_Error.PNG 

そこで、メッセージに従って ドングルを刺してから [OK] で、正常起動する。




CcLinker の終了

USBドングルを外す前に、CcLinkerアプリを必ず先に終了させる。
そうでないとエラーになり、結局 CcLinkerを強制終了することになる。



CcLinker の操作
 
CcLinkerアプリには [AC] ボタンしかない。基本操作は 接続した fx-5800P で行い、PC上ではファイルやフォルダの選択操作のみを行うようになっている。

fx-5800P からPCへ特定のプログラムファイルを転送 (PCにバックアップ)

CcLinker は、fx-5800P のプログラムファイルを CCL ファイル (CcLinker独自フォーマットのファイル形式)でバックアップする。

試しに、"fx-5800P【ゲーム】:Hit & Blow" で作ったプログラムのメインルーチンをPCにバックアップしてみる。私の fx-5800P ではメインルーチンのプログラム名を HB に変更している。

fx-5800Pを繋いだUSBドングルをPCに挿入した後 CcLinkerアプリを起動。


Pclink_fx-5800P   CcLinkerV4_Booted  

アプリでは何もせず、fx-5800P で、[MODE] - [▼] - [1] (LINK) - [1] (Transmit] - [2] (Select) と押し、
Select Data で バックアップしたいプログラム (今は "HB") にカーソルを合わせ、[1](SEL) を押し、最後に [0] (TRAN) を押す。
Transmit OK?[EXE] (Yes) を押すと、PCの一時ファイルに一旦バックアップされ、 fx-5800P で Completed! と表示される。

CompleteSaveV4 

そして、バックアップ先を選択するフォルダの選択画面が現れるので、そこでハックアップ先のフォルダを指定する。

SelectSaveFolder   

ファイル名を変更せず、そのまま [開く] ボタンをクリックすると、一時フォルダに一旦転送されたファイルが、指定したフォルダに移動される。


ここで最初に表示されるファイル名は、fx-5800Pに保存されているファイル名のうしろに COMP [ファイルサイズ] の情報が付加されている。この例では、HB COMP 027.cll になっている。ここでファイル名を自由に変更可能で、変更されたファイル名でバックアップできる。

なお、HB COMP 0127 の "COMP 0127" の部分は 必ずしも必要ではなく、消してしまっても問題ない。COMPモードのファイルであることを明示的に示すだけで、0127 はファイルサイズだ。

このファイル選択画面は、いわゆるコモンダイアログになっており、右クリックして現れるメニューから新規にフォルダを作ってからそこへ保存するなど Windows標準の操作ができる。


fx-5800P からPCへ全てのファイルを一気に転送 (PCに全てバックアップ) - Ver 1.7 以降 [2018/08/18]

fx-5800P のプログラムを全て一気にPCに転送できる。

上と同じ要領で、fx-5800P とPC を USBドングルで接続してから、CcLinker アプリを起動する。

CcLinkerアプリでは何もせず、fx-5800P で [MODE] - [▼] - [1] (LINK) - [1] (Transmit) - [1] (All) 、そして [EXE] をキーインする。

すると、「ファイルを選択してください」ダイアログが現れるので、バックアップするフォルダに移動するか、右クリックして新たにフォルダを作り、 [開く(O)]をクリックするか PCの [Enter] キーを押す。これで、電卓内の全てのプログラムがPCへ転送される。

保存先フォルダに同名ファイルがある場合は次のポップアップが現れる。

OverwriteFile  

ここで、[はい(Y)] を押すと、他に同名ファイルがあっても上書きコピーされる。無事に転送が終わると、fx-5800P と CcLinker アプリの両方で Completed! と表示される。

上書き確認は安全のため表示されるが、頻繁に表示され面倒になり、バックアップを中止したい時は、[キャンセル] を押せば、一連の転送そのものをキャンセルできる。

なお、何かエラーが発生したら、エラーメッセージが表示される。エラーメッセージで [OK] をクリック後、CcLinker アプリで [AC] をクリックして一旦バックアップを中止し、バックアップをやり直す。何度か繰り返す必要があるかも知れない。


PCから fx-5800P へ特定のプログラムファイルを転送 (電卓に転送)

CcLinker でバックアップしたCCLファイルを fx-5800P にプログラムファイルとして転送する。

fx-5800P をUSBドングルに繋いだ上で、ドングルをPCに刺し、CcLinkerアプリを起動する。

CcLinkerV4_Booted     

CcLinker アプリでは何もせず、fx-5800P で [MODE] - [▼] - [1] (1:LINK) - [2] (Receive) と押すと、保存するファイルの選択画面が現れる。

SelectResumingFile  

このファイル選択ダイアログで、転送したいファイルを選び [開く] ボタンをクリック。

既に同名ファイルがある場合は、上書きして良いかを確認するメッセージが現れるので、

OverwriteFile   

[はい(Y)][いいえ(N)] をクリックして先に進む。

OverWightBackFile_Disp 

無事に転送されると、fx-5800P と CcLinker の両方で Complete! と表示される。

BackUpAllCOmplete.png 




PCから fx-5800P へ全てのファイルを一気に転送 (電卓に全て転送)  [2018/08/18]

PCにバックアップしたファイルを一気に fx-5800P に転送できる。

fx-5800P で [MODE] - [▼] - [1] (LINK) - [2] (Receive) をキーイン。CcLinker アプリで [Transmit] クリックする。するとTransmit コモンダイアログが開くので、そこでfx-5800P へ転送するファイルのあるバックアップフォルダを開き、転送するファイルを選ぶ。[Ctrl]-[A] で全て選択するか、[SHIFT][Ctrl] を押しながら複数ファイルを選択し、[開く(O)] クリック。これで、選択したファイルが一気に fx-5800P に転送される。

転送が無事に完了した時は、fx-5800P と CcLinkerアプリの両方で Completed! と表示される。

fx-5800P に同名ファイルが有る場合は、見つかる度に以下のポップアップが表示される。

OverWightBackFile 

転送を中止したいときは、fx-5800P で [AC] (Cancel) を押すか、このダイアログで [キャンセル] をクリックする。




fx-5800P プログラムをCCLファイルで公開

当ブログで公開している fx-5800P 用プログラムファイルは、今後 CCLファイルでダウンロードできるようにしてゆく予定だ。

これまでは、プログラムを fx-5800P に手入力するしかなかったが、ダウンロードしたCCLファイルを CcLinker を使って fx-5800P に転送できるので、インターネットを使った fx-5800P のプログラムの流通が容易になる。



CcEditor

Takumako様のホームページ では、CcEditor が公開されている。

これを使うと、fx-5800P の Casio Basic をPC上でコーディングし、CcLinker で扱える CCL ファイルに変換できる。CCL ファイルを変更し、CCLファイルに変換することも可能だ。

それ以上に CcEditor の面白いところは、fx-5800P の Casio Basic で公開されていない機能を使うことが出来る点にある。
  • 表示文字列としてアルファベットの小文字、ギリシャ文字(大文字と小文字)が自由に使える
  • 変数にアルファベット小文字やギリシャ文字(大文字と小文字)が使える
  • 変数に添え字として数字アルファベットギリシャ文字を使える。
"fx-5800P Casio Basic をPCでコーディング - CcEditor" を参照。 

CcLinkerCcEditor を併用すると、fx-5800P の隠し機能として、表示に小文字が使え、使える変数が大幅に増加するので、fx-5800 Casio Basic プログラミングの幅が大きく広がる。



今後、何か分かれば随時追記修正してゆく。



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


 


keywords: fx-5800PCasioBasic、データリンク、CcLinker

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


関連記事

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

グラフ関数電卓 - 高速素因数分解、15桁対応

2020/08/15
追記:2020/08/15
修正:2020/08/17
追記:2020/08/21
追記・修正:2020/10/11
Windowsアプリアップデート&追記修正:2020/12/06
バグフィックス:2021/01/02

以前、fx-5800P の素因数分解の高速化プログラムを紹介しています。
fx-5800P 素因数分解 - 高速化

さらに、これをグラフ関数電卓に移植しました。
 グラフ関数電卓用 FactorG のダウンロード [2021/01/02 バグフィックス]
  バグフィックス:終了時に行列を解放しない点を修正し、不要なWhileEndを削除しました。
このプログラムは、純正Casio Basic用であり、純正Casio Basic は計算精度が得られるのは最大 10桁に制限されているので、プログラムの入力値は最大10桁になっていて、10桁を超えるとエラーを出して終了するようにしています。

その後、この FactorG を fx-CG50 の Python モード(Casio Python) に移植し、さらに15桁対応しました。
Casio Python - 要素数の多いリスト:高速素因数分解(5)

そこで、Casio Basic プログラムも15桁入力対応しようと考えました。純正Casio Basicでは、10桁の精度しかありません。しかし、上位互換であるアドイン版Casio Basic - C.Basic では15桁まで計算精度が得られるので、今回は C.Basic で走らせることを前提にして、純正Casio Basicで作った FactorG プログラムを15桁対応に変更します。


15桁入力に拡張するための条件

15桁入力に拡張するには計算精度が15桁であることが条件で、それを満たすのは、グラフ関数電卓のなかで、Pythonモード (Casio Python) と アドイン版 Casio Basic (C.Basic) が走る下記のモデルが必要です。

Casio Python が走るグラフ関数電卓のモデル
  • fx-CG50 OS3.2 以降
  • fx-9750GIII / fx-9860GIII

C.Basic が走るグラフ関数電卓のモデル
  • fx-9860G / fx-9860G SD / fx-9860G Slim (C.Basic for FX)
  • fx-9860GII / fx-9860GII SD (C.Basic for FX)
  • fx-9750GIII / fx-9860GIII (C.Basic for FX)
  • fx-CG20 / fx-CG50 (C.Basic for CG)

15桁入力に拡張した Casio Python スクリプト

以下の記事で紹介しているので、そちらを参照してください。
Casio Python - 要素数の多いリスト:高速素因数分解(5)

スクリプトは下記からダウンロードできます。
FactorG5 - Python スクリプト FactorG5.py (Ver 5.0)

FactorG5_input15 FactorG5_result 


15桁入力に拡張した C.Basic プログラム

今回は、以下のような C.Basic プログラムを作成します。

FactorG2_input15 FactorG2_result2  

そこで、以前作った10桁対応の以下のメインルーチン FACTORG.g3m とサブルーチン WFSUB.g3m を修正する作戦で進めます。そのために、以前作成した 10桁対応の FACTORG をダウンロードしておきます。
10桁対応の FACTORG ファイルのダウンロード [2021/01/02 バグフィックス]
  バグフィックス:終了時に行列解放しない点を修正し、不要なWhileEndを削除しました。

ダウンロードしたファイル FactorG.zip には、FXシリーズ (fx-9860G, fx-9860GII, fx-9750GIII, fx-9860GIII)で使える g1m ファイル、CGシリーズ (fx-CG20, fx-CG50) で使える g3m ファイル、そしてテキストファイルを同梱しています。C.Basic は、テキストファイルを読み込んで実行したり、g3m ファイルや g1m ファイルに変換できます。そこでテキストファイルをメモ帳で編集して 15桁対応に変更し、それを読み込んでからプログラムファイルに変換します。

さらに、15桁精度に対応していない純正Casio Basic で走らせることは考えなくて良いので、純正 Casio Basic に未対応の C.Basic 独自の拡張コマンドを活用してゆきます。

C.Basic については、FXシリーズ用の C.Basic for FX、そして CGシリーズ用の C.Basic for CG があり、それぞれ対応したバージョンをインストールして使えます。fx-9860G 以降の全てのグラフ関数電卓に対応しています。C.Basic については、下記 から必要なダウンロード、必要な説明を参照できます。 
アドイン版 Casio Basic - トップページ

今回は、fx-CG50C.Basic for CG を使います。


15桁入力対応高速素因数分解プログラムへの修正箇所

FACTORG
{1,22}->Dim Mat Z  ◀修正対象
"NUMBER"?->F
If F<1 Or F>=1Exp10 ◀ 修正対象
Then "NUMBER MUST BE >=1 And <1Exp10" ◀修正対象
Stop
IfEnd
If F<>Int (F)
Then "NUMBER MUST BE AN INTEGER" ◀修正対象
Stop
IfEnd
For 1->E To 22  ◀修正対象
0->Mat Z[1,E]
Next
0->Mat Z[1,1]  ◀修正対象
0->Mat Z[1,12]  ◀修正対象
0->E
F->A
Int (Sqrt(A))->C
2->B:A/B->D:Frac (D)=0=>Prog "WFSUB":B>C=>Goto 1
3->B:A/B->D:Frac (D)=0=>Prog "WFSUB":B>C=>Goto 1
5->B:A/B->D:Frac (D)=0=>Prog "WFSUB":B>C=>Goto 1
7->B:A/B->D:Frac (D)=0=>Prog "WFSUB":B>C=>Goto 1
11->B:A/B->D:Frac (D)=0=>Prog "WFSUB":B>C=>Goto 1
                             ◀追加
While 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB":B>C=>Goto 1
・・・
・・・  ◀このWhileループは全面差替え
・・・
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB":B>C=>Goto 1
WhileEnd

Lbl 1
If A>1
Then Isz E
A->Mat Z[1,E]
1->A
1->Mat Z[1,E+11] ◀修正対象
IfEnd
Int (E/6)->D
E-6*D>0=>Isz D
1->C

Lbl 2
ClrText
Locate 1,1,F    ◀修正対象
Locate 12,1,C  ◀修正対象
Locate 13,1,":" ◀修正対象
Locate 14,1,D  ◀修正対象
6*(C-1)+1->B
Locate 1,2,Mat Z[1,B]    ◀修正対象
Locate 11,2,"^("        ◀修正対象
Locate 13,2,Mat Z[1,B+11] ◀修正対象
Locate 16,2,")"         ◀修正対象
If B+1<=E
Then Locate 1,3,Mat Z[1,B+1] ◀修正対象
Locate 11,3,"^("         ◀修正対象
Locate 13,3,Mat Z[1,B+12]    ◀修正対象
Locate 16,3,")"          ◀修正対象
IfEnd
If B+2<=E
Then Locate 1,4,Mat Z[1,B+2] ◀修正対象
Locate 11,4,"^("         ◀修正対象
Locate 13,4,Mat Z[1,B+13]    ◀修正対象
Locate 16,4,")"          ◀修正対象
IfEnd
If B+3<=E
Then Locate 1,5,Mat Z[1,B+3] ◀修正対象
Locate 11,5,"^("         ◀修正対象
Locate 13,5,Mat Z[1,B+14]    ◀修正対象
Locate 16,5,")"          ◀修正対象
IfEnd
If B+4<=E
Then Locate 1,6,Mat Z[1,B+4] ◀修正対象
Locate 11,6,"^("         ◀修正対象
Locate 13,6,Mat Z[1,B+15]    ◀修正対象
Locate 16,6,")"          ◀修正対象
IfEnd
If B+5<=E
Then Locate 1,7,Mat Z[1,B+5] ◀修正対象
Locate 11,7,"^("         ◀修正対象
Locate 13,7,Mat Z[1,B+16]    ◀修正対象
Locate 16,7,")"          ◀修正対象
IfEnd

While Getkey:WhileEnd     ◀修正対象

Do
Getkey->K            ◀修正対象
LpWhile K=0
While Getkey            ◀修正対象 
WhileEnd             ◀修正対象
0->M
If K=47 Or K=44
Then 1->M
Else If K=27 Or K=37 Or K=31
Then 2->M
Else If K=28 Or K=38 Or K=41
Then 3->M
Else Goto 2
IfEnd:IfEnd
IfEnd

If M=1
Then ClrText
"DONE"
Else If M=2
Then Isz C
C>D=>1->C
Goto 2
Else If M=3
Then C-1->C
C<1=>D->C
Goto 2
IfEnd:IfEnd
IfEnd
ClrMat Z


WFSUB
E+1->E
B->Mat Z[1,E]
Do
D->A
Mat Z[1,E+11]+1->Mat Z[1,E+11] ◀修正対象
A/B->D
LpWhile Frac (D)=0
Int (SqrtA)->C
Return


上でダウンロードした FactorG.zip に同梱してあるテキストファイル FACTORG.txt を編集し、以下の具体的な変更を行います。完成した後、C.Basic 内蔵機能により g3m ファイルに変換して完成させます。


(1) 不要な初期化を削除
For 1->E To 22
0->Mat Z[1,E]
Next
0->Mat Z[1,1]
0->Mat Z[1,12]

0->E
F->A


変数の初期化のうち、For 文で行列 Z を全て 0 に初期化されているので、上記赤文字の初期化は不要です。従って削除します。


(2) 行列の確保領域の拡大に伴う変更
入力桁数を拡大するにともない、見つかる素因数の数も増えるので、素因数を格納する行列をほぼ倍に拡大します。
オレンジ色で示した部分は、以下のようにします。修正部分は赤文字にします。
行列確保の 2142 に変更、1121 に変更します。


FACTORG2
{1,42}->Dim Mat Z
・・・
For 1->E To 42
0->Mat Z[1,E]
Next

・・・
1->Mat Z[1,E+21]


WFSUB2
・・・
Mat Z[1,E+21]+1->Mat Z[1,E+21]
・・・


(3) 入力値の桁数制限を15桁にするための変更
入力値の制限とエラーメッセージを15桁対応にするため、修正文を赤文字にします。

FACTORG2
If F<1 Or F>=1Exp15
Then "NUMBER MUST BE    >=1 And <1Exp15"
Stop
IfEnd
If F<>Int (F)
Then "NUMBER MUST BE    AN INTEGER"


エラーメッセージは、BE のあとのスペースを7個にしすることで、表示した時に改行したようにみせます。


(4) Lbl 2 以下を、入力値と素因数の桁数増加に合わせて変更

C.Basic は計算精度は15桁ですが、設定によっては数値を出力する際に10桁を超えると指数表示になります。C.Basic では Norm の機能が拡張されていて、プログラム冒頭で Norm15 と記述するだけで 15桁までは指数表示されないように設定できます。今回はもう一つの方法として、数値を文字列に変更して Locate で出力する方法で変更してみます。Norm15 の方がスマートでコードがスッキリするかも知れませんが、今回は文字列を使うベタなやり方にしてみます。

以下のサンプルプログラムを見て下さい。

?->F
ToStr(F)->Str 1
log F>=10=>ToStr(Int(F÷E10))+ToStr(F-Int(F÷E10)×E10 )->Str 1
Locate 1,1,Str 1


値を入力させ、それを文字列に変換してLocate で出力するサンプルです。このコードを使います。

画面1行目に入力値と出力ページを出力する部分は、以下のようになります。変更箇所は赤文字で示します。

Lbl 2
ClrText
ToStr(F)->Str 1
log F>=10=>ToStr(Int (F/Exp10))+ToStr(F-Int (F/Exp10)*Exp10)->Str 1

Locate 1,1,Str 1
Locate 18,1,C
Locate 19,1,":"
Locate 20,1,D


このコードの下に、求めた素因数を1ページ分出力するコードが続きます。以下のように修正します。変更箇所は赤文字で示します。

6*(C-1)+1->B
Mat Z[1,B]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,2,Str 1
Locate 16,2,"^("
Locate 18,2,Mat Z[1,B+21]
Locate 21,2,")"
If B+1<=E
Then
Mat Z[1,B+1]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,3,Str 1
Locate 16,3,"^("
Locate 18,3,Mat Z[1,B+22]
Locate 21,3,")"
IfEnd
If B+2<=E
Then
Mat Z[1,B+2]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1

Locate 1,4,Str 1
Locate 16,4,"^("
Locate 18,4,Mat Z[1,B+23]
Locate 21,4,")"
IfEnd
If B+3<=E
Then
Mat Z[1,B+3]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1

Locate 1,5,Str 1
Locate 16,5,"^("
Locate 18,5,Mat Z[1,B+24]
Locate 21,5,")"
IfEnd
If B+4<=E
Then
Mat Z[1,B+4]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,6,Str 1

Locate 16,6,"^("
Locate 18,6,Mat Z[1,B+25]
Locate 21,6,")"
IfEnd
If B+5<=E
Then
Mat Z[1,B+5]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1

Locate 1,7,Str 1
Locate 16,7,"^("
Locate 18,7,Mat Z[1,B+26]
Locate 21,7,")"
IfEnd


(5) 素因数探索コード自体の変更

最初に素数2,3,5,7、11 で割り算して素因数を探索する部分は、さらに素数 13 で割り算するように追加します(赤文字)。

Int (Sqrt(A))->C
2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
3->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
5->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
7->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
11->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
13->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1



さて、これに続くWhile ループでは、以下のように Bに増分 (4, 2, 4, 6, ...) を加えて探索数とし、それで割り算して探索数を得る処理を1行で記述している。
While 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1

・・・
・・・
・・・

以前作っているコードでは、2,3,5,7 のいずれの倍数でもない 13 ~ 222 までの 48 個の探索数を用いている。今回は探索数を増やすため、2, 3, 5, 7, 11 のいずれの倍数でもない 17~2325までの 480 個の探索数に拡張して、さらに高速化を試みます。

但し、探索数の増分の計算そして 480 行の記述をエディタで作成するのは非現実的なので、480個の増分の計算とWhlle ループの中の480行の記述を作成して出力するWindowsアプリを作って、カット&ペーストで一気に作成することにします。

 FactorG2 作成支援 Windowsアプリ - SearchNumCG11 のダウンロード

ダウンロードするファイル SearchNumCB11.zip には、実行ファイル SearchNumCB11.exe と C#のソースファイルを同梱しています。 Visual Studio 2019 Community で作成しました。

実際にタイプして作った肝心のコードは以下です。
(参考) C# では、以下の CalcNum() 関数の実装部分と CalcNum() 関数を呼び出す1行の記述(合計21行)以外は一切コーディングせず、プロパティの設定を行うだけでWindowsアプリを作れることを申し添えておきます。チョット慣れれば、この程度の簡易的なWindowsアプリが簡単かつ迅速に作れるので、大変お勧めです。C#入門講座 など、ご自分に合った入門講座を探してみて下さい。
#foreachループ内の Result.AppendText() は速度低下するけど、この程度なら許せるので許してください。Casio Basic作成支援やCasio Pyton作成支援で作った一連のSearchNumでは、この速度低下に対応したものもあります。詳しくはダウンロードしたソースを見てください。


private void CalcNum()
{
 int prev_num = 13;
 int m = 17;
 int n = 2*3*5*7*11;
 int line = 0;
 String str = "";
 foreach (int num in Enumerable.Range(m,n))
 {
  if ((num % 2) * (num % 3) * (num % 5) * (num % 7) * (num % 11) != 0)
  {
   str = "B+" + (num - prev_num).ToString() + "->B:A/B->D:Frac (D)=0=>Prog \"WFSUB2\":B>C=>Goto 1";
   prev_num = num;
   Result.AppendText(str + "\r\n");
   line++;
  }
 }
 Result.AppendText("\r\n" + line.ToString() + " lines");
 Calc.Enabled = false;
}

整数 num に 17~2326 までの整数を適用し、num が 2, 3, 5, 7, 11 のいずれかの倍数でもない時の num を探索数と識別し、1つ前の num との差 (num - prev_num) を [増分] とし、順次
B+[増分]->B:A/B->D:Frac (D)=0=>Prog "WFSUB2:B>C=>Goto 1
をテキストボックスに出力します。

さっそく SearchNumCB11.exe を起動します。
SearchCB11_input 

[Calculate] ボタンをクリックすると必要な記述が出力されます。
SearchCB11_result 

テキストボックス内は、自由に編集ができます。テキストボックスから必要な部分をカットコピーし、エディタで開いた FACTORG2.txt のなかで該当する While 1WhileEnd の間にペーストします。

例えば、テキストボックスで [Ctrl]+[A] で全てを選択し、[Shift]+[↑] を押してから [Ctrl]+[C] でコピーし、エディタで開いた FACTORG2.txt の 該当部分に [Ctrl]+[V]でペーストします。これで、480行のコードが一気に完成します。

一見回りくどいようですが、タイプミスの抑制と作業全体のタイプ量の大幅な節約、そしてなにより時間の節約になったと思います。


(6) 出力に色を付け、同じコードでモノクロ液晶機種用 g1m ファイルとの互換性を保つ

目標の出力を以下のようにします。
FactorG2_result2 

入力値を、乗数の ^( )で出力するには、red Locateblue Locateとします。
但し、色指定は カラー液晶を搭載した fx-CGシリーズのみで有効となり、モノクロ液晶の fx-9860Gシリーズや fx-9750GIII ではエラーになります。そこで、C.Basic の拡張コマンド System(-1) を使って機種判定を行い、CGシリーズの時は色指定をしたLocateコマンドを実行し、そうでない時は色指定なしの Locate コマンドを実行させれば良いわけです。
System(-1) は、CGシリーズでは 10 以上の整数を返し、それ以外では1桁の整数を返します。

そこで、プログラムの冒頭で機種判断を行うことにします。
0->G:System(-1)>=10=>1->G

このように、変数G を 0 で初期化しておき、CGシリーズの時は 1 になるようにしておきます。

CGシリーズで赤で出力する場合、モノクロ機種で色指定をしないために、
If G:Red Locate 1,1,Str 1
Else Locate 1,1,Str 1:IfEnd


CGシリーズで青で出力する場合、モノクロ機種で色指定をしないために、
If G:Blue Locate 16,2,"^("
Else Locate 16,2,"^(":IfEnd


If G:Blue Locate 21,2,")"
Else Locate 21,2,")":IfEnd


とします。

以上を適用すると Lbl 2 以降は、以下のようになります。修正した部分を赤文字で示します。

Lbl 2
ClrText
ToStr(F)->Str 1
log F>=10=>ToStr(Int (F/Exp10))+ToStr(F-Int (F/Exp10)*Exp10)->Str 1
If G:Red Locate 1,1,Str 1
Else
Locate 1,1,Str 1:IfEnd
Locate 18,1,C
Locate 19,1,":"
Locate 20,1,D
6*(C-1)+1->B
Mat Z[1,B]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,2,Str 1
If G:Blue Locate 16,2,"^("
Else
Locate 16,2,"^(":IfEnd
Locate 18,2,Mat Z[1,B+21]
If G:Blue Locate 21,2,")"
Else
Locate 21,2,")":IfEnd
If B+1<=E
Then
Mat Z[1,B+1]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,3,Str 1
If G:Blue Locate 16,3,"^("
Else
Locate 16,3,"^(":IfEnd
Locate 18,3,Mat Z[1,B+22]
If G:Blue Locate 21,3,")"
Else
Locate 21,3,")":IfEnd
IfEnd
If B+2<=E
Then
Mat Z[1,B+2]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,4,Str 1
If G:Blue Locate 16,4,"^("
Else
Locate 16,4,"^(":IfEnd
Locate 18,4,Mat Z[1,B+23]
If G:Blue Locate 21,4,")"
Else
Locate 21,4,")":IfEnd
IfEnd
If B+3<=E
Then
Mat Z[1,B+3]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,5,Str 1
If G:Blue Locate 16,5,"^("
Else
Locate 16,5,"^(":IfEnd
Locate 18,5,Mat Z[1,B+24]
If G:Blue Locate 21,5,")"
Else
Locate 21,5,")":IfEnd
IfEnd
If B+4<=E
Then
Mat Z[1,B+4]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,6,Str 1
If G:Blue Locate 16,6,"^("
Else
Locate 16,6,"^(":IfEnd
Locate 18,6,Mat Z[1,B+25]
If G:Blue Locate 21,6,")"
Else
Locate 21,6,")":IfEnd
IfEnd
If B+5<=E
Then
Mat Z[1,B+5]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,7,Str 1
If G:Blue Locate 16,7,"^("
Else
Locate 16,7,"^(":IfEnd
Locate 18,7,Mat Z[1,B+26]
If G:Blue Locate 21,7,")"
Else
Locate 21,7,")":IfEnd
IfEnd


以上のようにすると、CGシリーズでもそれ以外でも互換性を保って動作可能になります。


(7) Getkey を Getkey1 に変更する
今回は、C.Basic専用のプログラムに変更するので、純正 Casio BasicGetkey コマンドを C.Basic拡張コマンド Getkey1 に置き換えます。Getkey コマンドは キーが押されるその時に実行されると キーコードを取得する仕様なので、キー取得はループの中に Geteky を記述しなければなりません。キー入力で動作を分岐する動作が連続するとき、同じキーを少し長めに押すと連続して同じキーが押されたと誤判定されることがあり、その際は 
While Getkey:WhileEnd
を記述して、キーが離されないと先に進めない機能(関所の機能)を設ける必要があります。

一方で、C.Basicの拡張コマンド Getkey1 は、キーが押されるまで待つ機能が付加されます。するとキーが離されないと先に進めないようにするループが不要になります。

(6) で検討した結果を出力するコードに続く、結果表示のページを切り替えるためのキー入力コードは以下のようになっています。

While Getkey:WhileEnd

Do
Getkey->K
LpWhile K=0
While Getkey
WhileEnd


Getkey->KGetkey1->K に変更した上で、以下のように変更できます。

Do
Getkey1->K
LpWhile K=0


変更前の以下のコードに含まれる2箇所の While Getkey:WhileEnd を削除します。


(8) g1m ファイルと g3m ファイルに変換する

これまでは、テキストファイルで編集してきました。C.Basic では、テキストファイルから g3m ファイルや g1m ファイルに変換できます。

FACTORG2.txtfx-CG50 に転送します。

次に、C.Basic のファイルリスト画面で FACTORG2.txt を選択
Select_txt_file 

[F6] (▷) を押し、
Coverting_txt_file 

さらに、[F1] (CONVERT) を押し、
Coverte_txt_file 

[F2] (g1m) を押せば、g1m ファイルに変換され、
[F3] (g3m) を押せば、g3m ファイルに変換されます。



15桁対応、高速素因数分解 - FACTORG2.g3m の実行

 ダウンロード:15桁対応・高速素因数分解 FACTORG2 (for C.Basic) 
  [2021/01/02 バグフィックス] バグフィックス:終了時に行列解放しない点を修正しました。

参考のため、以前作った Pythonモード (Casio Python) の FactorG5.py の実行結果と比較します。

search_30445_f  CBResult2_1 

Search_39969_f  CBResult2_2 

seach_47824_f  CBResult2_3 
Case1_14digit  CBResult2_4 

search_90872_f  CBResult2_5 

search_189426_f.png  CBResult2_6 
search_263027_f.png  CBResult2_7 

search_343013_f.png  CBResult2_8 

search_2025804_f.png  CBResult2_9 
search_4349444_f.png  CBResult2_10 


表2- 15桁版高速素因数分解実行時間の違い - Casio Python と C.Basic の比較
    (fx-CG50 OS3.4 使用)
Casio Python
FactorG5.py
C.Basic
FACTORG2.g3m
 WFSUB2.g3m
高速化
入力値実行時間 [秒]実行時間 [秒]時間差 [%]
547,896,321,054,789 8.74.350.6
7,845,162,037,849 11.45.452.6
748,159,026,374,815 13.76.453.3
36,209,518,473,620 15.57.551.6
986,753,421,098,675 
26.011.854.6
96,835,724,130,261 52.724.952.8
748,159,026,396,835 73.134.353.1
96,835,724,136,209 95.344.653.2
748,159,026,336,209 585.0
(9分45秒)
255.8
 (4分15.8秒)
56.3
362,095,184,736,209 1,235.6
(20分35.6秒)
553.3
(9分13.3秒)
55.2

Casio Python よりも C.Basic が2倍程度高速だと分かりました。

現状の Casio Python では、動作中にリアルタイムでキー入力を受け付けることができません。一方、純正 Casio BasicC.Basic ではリアルタイムキー入力が可能なので、プログラミング言語としてはより実用的と言えます。


さらに高速化する [2020/08/15 追記]

さらに高速化するために今回拡張した While ループ内で実行する探索数をさらに増やしてみました。

素数での割り算を2~13に加えて17での割り算を追加し、それに続く Whileループでの素因数探索を 2, 3, 5, 7, 11, 13のいずれの倍数でない整数で割り算するように拡張してみました。すると、このループ内は 5760 行となります。上と同様に新たに専用Windowsアプリを作成し、カット&ペーストで追加し、FACTORG3.g3m を作成しました。

FACTORG3.g3m 作成支援アプリ - SearchNumCB13 ver2.0 のダウンロード 
 ※ [2020/12/06 ver2.0 にアップデート - 処理の大幅な高速化]

これを実行すると以下のように出力されます。
SearchCB13_result

5760行ものコードを追加すると、FACTORG3.g3m のファイルサイズは 210,028 バイト (210Kバイト) になり、上で作った FACTORG2.g3m の10倍程度の大きなファイルです。

幸い fx-CG50 では実行可能で、上で作成した FACTORG2.g3m よりも 7% 程度高速化しました。
15桁対応高速素因数分解プログラム - FACTORG3.zip のダウンロード

現在のところ、C.Basic for CG で動作する FACTORG3.g3m が最速です。
但し、ファイルサイズがあまりにも大きくメモリを無駄食いする割に、7%程度の高速化なので、管理人としては FACTORG2.g3m を推奨したいと思います。

なお、FACTORG3.zip に同梱している FACTORG3.g1m (モノクロ機種用) は、C.Basic for FX ではファイルサイズが大きすぎて実行できないので、上で作った FACTORG2.g1m がモノクロ液晶機種対応としては、最速になります。従って、g1m と g3m で互換性のある FACTORG2 (g1m/g3m互換) をやはり推奨したいと思います。


もう一段高速化を試みる

探索数をさらに拡張した FACTORG4.g3m について
同様に、FACTORG4 作成支援アプリ SearchNumCB17 [2020/12/06 Ver2.0 にアップデート、処理の高速化]  を作って実行させると、なんと 92160 行ものコードを生成します。

SearchCB17_result

この出力をカット&ペーストして、テキストファイル FACTORG4.txt を作成すると 4787 Kバイト (4.8Mバイト) となり、fx-CG50 のストレージメモリの最大容量である 1.6 Mバイトを超えてしまい、メモリ不足で fx-CG50 に転送できません。ここが限界のようです。

最速は、FACTORG3.g3m で、実用的には FACTORG2.g3m で十分だという結論にしておこうと思います。
===== [2020/08/15 追記] 終わり =====


モノクロ機種での FACTORG2.g1m の実行

fx-9750GIII で 15桁対応高速素因数分解 - FACTORG2.g1m を実行してみます。 

CBMResult 

CBMResult_11 CBMResult_12 CBMResult_13 

fx-9750GIIIfx-9860Gシリーズ (fx-9860GIIIfx-9860GII, fx-9860GII SDfx-9860G, fx-9860G SD, fx-9860G Slim) にインストールした C.Basic for FX でも自動機種判定がうまくいって、同様の出力が得られることが確認できました。


今回作成したコード (テキストファイルの表記)

 ダウンロード:15桁対応・高速素因数分解プログラム - FACTORG2 (for C.Basic)

今回紹介したような支援アプリを使わないと到底作成ができないことがよく分かります。


FACTORG2.txt
0->G:System((-)1)>=10=>1->G
{1,42}->Dim Mat Z
"NUMBER"?->F
If F<1 Or F>=1Exp15
Then "NUMBER MUST BE >=1 And <1Exp15"
Stop
IfEnd
If F<>Int (F)
Then "NUMBER MUST BE AN INTEGER"
Stop
IfEnd
For 1->E To 42
0->Mat Z[1,E]
Next
0->E
F->A
Int (Sqrt(A))->C
2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
3->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
5->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
7->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
11->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
13->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
While 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+14->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+12->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+12->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+12->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+12->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+12->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+12->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+10->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+14->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+8->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+6->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+4->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+12->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+2->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
B+12->B:A/B->D:Frac (D)=0=>Prog "WFSUB2":B>C=>Goto 1
WhileEnd

Lbl 1
If A>1
Then Isz E
A->Mat Z[1,E]
1->A
1->Mat Z[1,E+21]
IfEnd
Int (E/6)->D
E-6*D>0=>Isz D
1->C

Lbl 2
ClrText
ToStr(F)->Str 1
log F>=10=>ToStr(Int (F/Exp10))+ToStr(F-Int (F/Exp10)*Exp10)->Str 1
If G:Red Locate 1,1,Str 1
Else Locate 1,1,Str 1:IfEnd
Locate 18,1,C
Locate 19,1,":"
Locate 20,1,D
6*(C-1)+1->B
Mat Z[1,B]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,2,Str 1
If G:Blue Locate 16,2,"^("
Else Locate 16,2,"^(":IfEnd
Locate 18,2,Mat Z[1,B+21]
If G:Blue Locate 21,2,")"
Else Locate 21,2,")":IfEnd
If B+1<=E
Then
Mat Z[1,B+1]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,3,Str 1
If G:Blue Locate 16,3,"^("
Else Locate 16,3,"^(":IfEnd
Locate 18,3,Mat Z[1,B+22]
If G:Blue Locate 21,3,")"
Else Locate 21,3,")":IfEnd
IfEnd
If B+2<=E
Then
Mat Z[1,B+2]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,4,Str 1
If G:Blue Locate 16,4,"^("
Else Locate 16,4,"^(":IfEnd
Locate 18,4,Mat Z[1,B+23]
If G:Blue Locate 21,4,")"
Else Locate 21,4,")":IfEnd
IfEnd
If B+3<=E
Then
Mat Z[1,B+3]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,5,Str 1
If G:Blue Locate 16,5,"^("
Else Locate 16,5,"^(":IfEnd
Locate 18,5,Mat Z[1,B+24]
If G:Blue Locate 21,5,")"
Else Locate 21,5,")":IfEnd
IfEnd
If B+4<=E
Then
Mat Z[1,B+4]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,6,Str 1
If G:Blue Locate 16,6,"^("
Else Locate 16,6,"^(":IfEnd
Locate 18,6,Mat Z[1,B+25]
If G:Blue Locate 21,6,")"
Else Locate 21,6,")":IfEnd
IfEnd
If B+5<=E
Then
Mat Z[1,B+5]->z
ToStr(z)->Str 1
log z>=10=>ToStr(Int (z/Exp10))+ToStr(z-Int (z/Exp10)*Exp10)->Str 1
Locate 1,7,Str 1
If G:Blue Locate 16,7,"^("
Else Locate 16,7,"^(":IfEnd
Locate 18,7,Mat Z[1,B+26]
If G:Blue Locate 21,7,")"
Else Locate 21,7,")":IfEnd
IfEnd

Do
Getkey1->K
LpWhile K=0
0->M
If K=47 Or K=44
Then 1->M
Else If K=27 Or K=37 Or K=31
Then 2->M
Else If K=28 Or K=38 Or K=41
Then 3->M
Else Goto 2
IfEnd:IfEnd
IfEnd

If M=1
Then ClrText
"DONE"
Else If M=2
Then Isz C
C>D=>1->C
Goto 2
Else If M=3
Then C-1->C
C<1=>D->C
Goto 2
IfEnd:IfEnd
IfEnd
ClrMat Z


WFSUB.txt
E+1->E
B->Mat Z[1,E]
Do
D->A
Mat Z[1,E+21]+1->Mat Z[1,E+21]
A/B->D
LpWhile Frac (D)=0
Int (SqrtA)->C
Return







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


 


keywords: プログラム関数電卓、fx-CG50、C.Basic、素因数分解、プログラミング、Casio Basic

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

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

fx-5800P 素因数分解 - さらなる高速化

2020/12/04
追記修正:2020/12/05
バグフィックス:2021/01/02


fx-5800P 素因数分解 - 高速化 で、Casio Basic プログラムによる素因数分解 の大幅な高速化を紹介していますが、今回はそれをさらに高速化できたので紹介します。

今回は高速化するために、あらゆる使えるものを総動員して fx-5800P Casio Basic プログラムを効率よく作成する、一風変わったアプローチを採用することになりました。


fx-5800P の Casio Basic プログラムをPCで編集

カシオは、fx-5800PのプログラムやデータをPCリンクする手段を提供していませんが、takumako様によりPCリンクするハードウェアとソフトウェア - CcLinker が提供されています。さらに fx-5800P の Casio Basic プログラムをPCで編集するためのエディタ - CcEditor が提供されています。

それぞれの使い方については、以下を参照してください。
 CcLinker - ついに fx-5800P がPCリンク可能になった を参照
 CcEditor - fx-5800P Casio Basic をPCでコーディング - CcEditor を参照


fx-5800P のプログラムをファイルに変換する
今回改造する fx-5800P の Casio Basic プログラム - Factor-F1 を CcLinker でPCに転送します。

FACTOR-F1 のダウンロード [2021/01/02 バグフィックス]
  バグフィックス:終了時に配列変数を解放しない点を修正し、不要な WhileEndを削除しました。
※ ダウンロードした zip ファイルには、fx-5800P で使う2つの ccl ファイルとそれらのテキストファイルを含んでいます。FACTOR-F1.cllWFSUB.ccl を fx-5800P に転送すれば、FACTOR-F1 を走らせられます。


CcLinkerドングルをPCに刺してから、fx-5800P をつなぎ、CcLinker ソフトウェアを起動します。
CcLinker_StartUp 

fx-5800P 素因数分解 - 高速化 で作ったプログラム FACTOR-F1 を fx-5800P から PC へ転送すると、転送したファイルを保存するコモンダイアログが現れます。
CcLinker_DownLoaded

ファイル名を FACTOR-F1.ccl にして、[開く] をクリック。
この場合は、Download フォルダにダウンロードしているので、Download フォルダに FACTOR-F1.ccl が作成されます。

FACTOR-F1 は サブルーチンとして WFSUB を使っています。結論から言えば WFSUB は変更しないので、そのままにしておきます。


FACTOR-F1.ccl を CcEditor で開く
今回編集するプログラムがファイル FACTOR-F1.ccl になったので、それを編集するために CcEditor で開きます。
CcEditor_Loaded

CcEditor で fx-5800P のプログラム FACTOR-F1 が編集できるようになりました。


素因数分解の基本的アルゴリズム

あらゆる整数は、素数の積で表せるので、その素数の積を求めるのが素因数分解です。
ところで、素数とは、1と自分自身以外で割り切れない (1と自分自身以外の約数がない) 整数です。
ちなみに、1は素数ではなく、2,3、5、7,11,13、17、19,23 ... と素数は無限にあります。

与えられた数 (自然数) をそれより小さい自然数 (=探索数) で割って、割り切れるかどうかを調べます、割り切れるかどうかを調べる自然数を探索数と呼ぶことにします。
  • 与えられた数を最小の素数2で割って割り切れたら、2は素因数の1つです。2で割り切れる場合は、何回2で割り切れるかを調べます。そして、2の倍数を探索数から除外します。
  • 2の次に大きな素数は3なので、与えられた数が3で割り切れるかどうかを調べ、割り切れる場合は何回3で割り切れるかどうかを調べます。そして、3の倍数も探索数から除外します。
  • 3の次に大きな素数は5なので、与えられた数が5で割り切れるかどうかを調べます。割り切れる場合は何回5で割り切れるかを調べます、そして探索数から5の倍数も除外します。
こうやって小さい順に素数を探索数として使うのが理想的ですが、素数でなくても問題ありません。いずれにしても、その倍数を使わないようにして探索数を絞り込む方法が "エラストテレスの篩い" と言われているものです。

与えられた数が平方数 (平方根が整数になる数) の場合、その平方根が素数であることもあり、その場合は最大の素因数になります。与えられた数の平方数でなくても、その平方根 より小さく。その平方根に一番近い整数が最大の探索数になります。

プログラムファイルのサイズの上限が限られ、プログラム実行速度が遅い fx-5800P の Casio Basic では、割り算に用いる探索数をどうやって効率よく絞り込むかが、プログラム高速化のポイントになります。


高速素因数分解のアルゴリズム

以前紹介した高速素因数分解のアルゴリズムは、エラストテレスの篩い を効率化したもので、具体的には以下の方法で探索数を絞り込んでいます。

 探索数増分数を48個使って、効率よく探索数を絞り込む方法
a) 素数 2, 3, 5, 7, 11 を探索数として除算を繰り返し、
b) 13以上で 2, 3, 5, 7 のいずれかの倍数でもない探索数は 13~222 までには 210個の整数のうち48個あり、その48個の探索数で除算を繰り返し、
a) b) それぞれの除算の結果から素因数を調べます。13~222までの210個の整数のうち48個まで探索数を絞り込んでいます。詳しくは、前回の記事 を参照してください。

a)
Int(√(A))→C↵
2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
3→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
5→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
7→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
11→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1

探索数 B に 2、3、5、7、11 を適用しています。探索数が与えられた整数 A の平方根より小さく、それに近い整数 C よりも探索数が大きくなれば Goto 1 で探索が終わります。
1回の探索を1行で表現しています。

b)
While 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
・・・・・
・・・・・

B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+10→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+10→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
WhileEnd↵

この While ループには48行の処理が含まれています。
a) で探索数 B は 11 になっており、増分 2、4、10 などを加えて新たな探索数にして、素因数探索を1行で処理しています。探索数が整数 A よりも小さく、さらに探索数が整数 C よりも大きい場合は、Goto 1 で探索が終わり、While ループを脱出します。ここで、ポイントはこの増分をどうやって求めるかです。48個程度なら手計算やエクセルを使って求められます。



今回は、同じロジックですが、エラストテレスの篩いをさらに効率化、つまり探索数の絞り込みをより効率化し、
探索の無駄をさらに減らすことによる計算の高速化
を試みます。

素数を探索数に用いる部分と、While ループ内の48行の探索部分を以下のように拡張します。

 探索数増分を増やして、素因数探索をさらに効率化する方法
A) 素数 2, 3, 5, 7, 11, 13 を探索数として除算を繰り返し、
B) 17以上で 2, 3, 5, 7, 11 のいずれかの倍数でもない探索数は、17~2326 までには480個あり、その480個の探索数で除算を繰り返し、
A) B) のそれぞれの除算の結果から素因数を調べます。17~2326 までの2310個の整数のうち480個の探索数まで絞りこんでいます。

探索数の取りこぼしを防ぐためには、周期2310の範囲で探索する必要があります。
念のため、探索数を 17~2326 の範囲で探し、それが480個になる説明は以下のようになります。
  • 2, 3, 5, 7, 11 の最小公倍数は 2310
  • 2, 3, 5, 7, 11 のいずれかの倍数でない探索数の増分は 2310 の周期
  • 探索数を17から調べるので、1周期の終わりは 2326
  • 2, 3, 5, 7, 11 のいずれの倍数でない整数の個数:480個
  • これの算出方法は以下の通り;
  •  2 の倍数の個数:2310/2 = 1155
  •  3 の倍数の個数:2310/3 = 770
  •  5 の倍数の個数:2310/5 = 462
  •  7 の倍数の個数:2310/7 = 330
  •  11 の倍数の個数:2310/11 = 210 ⇒ 以上の合計:2927個
  • .
  •  2と3の公倍数の個数:2310/6 = 385
  •  2と5の公倍数の個数:2310/10 = 231
  •  2と7の公倍数の個数:2310/14 = 165
  •  2と11の公倍数の個数:2310/11 = 105
  •  3と5の公倍数の個数:2310/15 = 154
  •  3と7の公倍数の個数:2310/21 = 110
  •  3と11の公倍数の個数:2310/33 = 70
  •  5と7の公倍数の個数:2310/35 = 66
  •  5と11の公倍数の個数:2310/55 = 42
  •  7と11の公倍数の個数:2310/77 = 30 ⇒ 以上の合計:1358個
  • .
  •  2と3と5の公倍数の個数:2310/2/3/5 = 77
  •  2と3と7の公倍数の個数:2310/2/3/7 = 55
  •  2と3と11の公倍数の個数:2310/2/3/11 = 35
  •  2と5と7の公倍数の個数:2310/2/5/7 = 33
  •  2と5と11の公倍数の個数:2310/2/5/11 = 21
  •  2と7と11の公倍数の個数:2310/2/7/11 = 15
  •  3と5と7の公倍数の個数:2310/3/5/7 = 22
  •  3と5と11の公倍数の個数:2310/3/5/11 = 14
  •  3と7と11の公倍数の個数:2310/3/7/11 = 10
  •  5と7と11の公倍数の個数:2310/5/7/11 = 6 ⇒ 以上の合計:288個
  • .
  •  2と3と5と7の公倍数の個数:2310/2/3/5 = 11
  •  2と3と5と11の公倍数の個数:2310/2/3/5/11 = 7
  •  2と3と7と11の公倍数の個数:2310/2/3/7/11 = 5
  •  2と5と7と11の公倍数の個数:2310/2/5/7/11 = 3
  •  3と5と7と11の公倍数の個数:2310/3/5/7/11 = 2 ⇒ 以上の合計:28個
  • .
  •  2と3と5と7と11の公倍数の個数:2310/2/3/5/7/11 = 1個
  • .
  •  以上から 2927 - 1358 + 288 - 28 + 1 = 480個
a)
Int(√(A))→C↵
2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
3→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
5→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
7→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
11→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
13→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1

探索数の素数に 13 を追加します。CcEditor で一番下の赤文字の行を追加します。

b)
While 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
・・・・・
・・・・・
B+12→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+12→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1

WhileEnd↵

この While ループには、480行の素数探索処理が含まれます。この赤文字の部分の特に探索数の増分をどうやって効率よくかつ間違いなく計算し、480行もの入力をどうやって間違いなく効率よく行うのか、そこが問題です。そこで、今回は赤文字の部分を自動的に作成することにしました。


コードの自動作成
さて、手計算やエクセルで480個の探索数増分を計算して、それに基づき480行もの大量の記述を間違いなくタイプして入力するのは、現実的ではなく、あまりにも非効率です。そこで、探索数の増分の計算や、480行のプログラムコード作成を自動化するWindowsアプリを作ります。使えるものは何でも使う作戦です。これにより、カット&ペーストで CcEditor の画面に追記するだけで、480行の追加を簡単かつ確実に行えます。

この480個の探索数の増分を計算し、480行の Casio Basic のコードを自動作成する Windows デスクトップアプリ SearchNum11_10digits.exe を Visual Studio 2019 Community の C# で作りました。少しだけ C# を使ったことがあれは、マウスクリックだけで殆どを自動作成してくれ、全部で20行程度のコーディングを行うだけで、比較的簡単に出来ると思います。

 480行のコードを生成するWindowsデスクトップアプリ
 - SearchNum11_10digits のダウンロード


ダウンロードファイルには、アプリの実行ファイル (SearchNum11_10digits.exe) だけでなくソースコードも同梱していますので、ご興味があればご覧頂くなり、ご自分でビルドしたり改造してお使いください。
※ C# については、以前軽く紹介しています ⇒ プログラム電卓のための Windowsプログラミング

ところで、新しいWindowsアプリは、初めて実行するとき Windowsの保護機能により、まるで危ないソフトのように扱われます。これはこれまで使った人が少ないというだけでも、保護機能が発動するようになっています。自作のWindowsアプリを自分で作って起動しても保護機能が発動してしまいます。この保護機能が発動したときに対処方法について 自作プログラムがPC保護機能に引っかかる にまとめていますので、参考にしてください。

このアプリの重要なコードは以下のようにしています (ご参考まで)。
SearchNum11CB_code

C# を使えば、上記の20行と、この関数を呼び出すための1行、合わせて21行をタイプしてコーディングするだけで、あとはマウスのクリック操作をチョコチョコと行うことで、デスクトップアプリが簡単かつ迅速に作れてしまうのが良いところです。


さて、SearchNum11_10digits.exe を起動したところ:
SearchNum11CB_10digits_starinting

右上の [Calculate] ボタンを押すと、While ループ内のコードがテキストボックスに出力されます。
SearchNum11CB_10digits_result
出力されると [Calculate] ボタンを押せなくしています。

テキストボックスでは、改行したり編集ができます。そこで、これをカットアンドペーストにより、プログラムをエディタで開き、必要なところに貼り付ければ、プログラム修正が簡単にできます。

例えば、上のテキストボックスの中でクリックしてから、[Ctrl]+[A] で全部を選択してから、[↑] キーを押して 最後の行の Goto 1 まで選択した状態にして、[Ctrl]+[C] でコピーしてから、

CcEditor エディタで、

While 1

WhileEnd


の間にカーソルを移動して、[Ctrl]+[V] とすればペーストできます。 


編集したコードを FACTOR-F2.ccl としてPCに保存する

CcEditor で メニューの右にある Project を FACTOR-F1 から FACTOR-F2 に変更します。
CcEditor_FACTOR-F2

[File] - [Ceck] を選択します。
CcEditor_Check

しばらく待つと、コードの種類別に色が付きます。
CcEditor_Checked

関数、コマンド、文字列ごとに異なる色が付きますが、これは fx-5800P Casio Basic の特殊コードの種別に応じて色分けされた結果です。色分けがおかしなところは、文法に合わないコードなので、fx-5800P で実行するとエラーになる可能性が高いわけです。色分けのおかしなところは、よく見て必要ならば修正します。 この色分けは CcEditor の親切機能で、お好みの色分け設定に変更できます。

慣れないとよく分からないかも知れませんが、その場合は次の操作へ進んで下さい。最終的に fx-5800P でエラーが発生したら、その部分を fx-5800P 上で修正するか、CcEditor で修正すれば良いです。

そして、[File] - [Build] を選択して、FACTOR-F2.ccl ファイルを作成 (ビルド) します。
CcEditor_Build

しばらく待つと、cclファイルを作成するかを聞いてくるので、[はい] をクリックします。
CcEditor_ccl

※参考
 CcEditor では、少し待つ間に上の例のようにタイトルバーに (応答なし) と表示されることがあります。これは CcEditor のバグではなくて仕様です。マルチスレッド処理を行わない普通のWindowsアプリでは、アプリがCPUを独占して使う時間が少し長めになると、ウィンドウ表示の更新など内部で行われるマルチタスク処理が止まってしまうので、(応答なし) と表示してしまうのが、この表示の正体です。なのでアプリの処理が終わるまで少し待てば良いことが殆どです。但しアプリのバグで処理が終わらない場合も同じように (応答なし) と表示され、アプリの処理に時間がかかっているだけなのか、バグなのかの区別が付かないのも事実ではあります。

少し待てば、保存するファイル名を決めるコモンダイアログが現れます。
CcEditor_save_ccl

ここでは、ダウンロード先を Download フォルダに指定し、[開く(O)] をクリックします。
[開く(O)] をクリックする前にファイル名を FACTOR-F2.ccl に変更してもOKなので、ここではそのようにします。
CcEditor_save_FACTORF2 

すると、Download フォルダに FACTOR-F2.ccl が作成されます。

FACTOR-F2.ccl のダウンロード [2021/01/02 バグフィックス]
   バグフィックス: 終了時に配列変数が解放されない点を修正し、不要なWhileEndを削除しました。
※ ダウンロードしたzipファイルには、fx-5800P に転送する2つのcclファイルと、それらのテキストファイルを含んでいます。


FACTOR-F2 を fx-5800P に転送して実行する

fx-5800P のプログラムメモリ容量は、最大 28,432 バイトです。一方、今作成した FACTOR-F2.ccl のファイルサイズは、21,456 バイトと結構大きなファイルです。サブプログラム WFSUB.ccl は 147 バイトなので、合計で 21,603 バイト必要となり、容量ギリギリになります。

既に fx-5800P に多くのプログラムがあって、空き容量が足りない時は、FACTOR-F2 を転送できません。そこで、サブプログラム WFSUB 以外のプログラムを CcLinker でPCに待避させた後、WFSUB 以外のプログラムを削除しておき、FACTOR-F2.cclCcLinker で fx-5800P に転送します。

さて、サブプログラム WFSUB は変更せず、そのまま使用します。FACTOR-F2 で、7,849,516,203 (= 3 x 9811 x 88897) を素因数分解し、その実行時間を計ってみます。

FACTOR-F1FACTOR-F2高速化
111秒101秒9.0%


fx-5800P 素因数分解のさらなる高速化が達成できました!


最後に [2020/12/05 追記]

実は先に Pythonモードの Casio Python で素因数分解を高速化したのと同じ手法をfx-5800P のCasio Basic に適用したのが今回の記事です。詳しくは、Casio Python - 要素数の多いリスト:高速素因数分解(5) の表2で示しているように、ループが回る回数が 9.1% 減少し、高速化が 9~10% でした。一方、今回の fx-5800P での高速化が 9.0% であり、これは Casio Python での高速化の結果とほぼ一致しています。従って、素数以外の探索数で計算する While ループの実行回数を削減したことが高速化の主要因要因だといえます。

上で紹介した Casio Python での検討では、素数以外の探索数をさらに拡張して、Whileループの実行回数をさらに減らすことも試していて、さらに高速化できています。ただしプログラムファイル(スクリプトファイル)が恐ろしいほど大きくなってしまうことも判りました。同じことを fx-5800P 用に行っても、できあがるプログラムのファイルサイズが大きすぎて fx-5800P のメモリに収まりません。

今回の fx-5800P で高速化した Casio Basic プログラムファイルは、fx-5800P のメモリ容量ギリギリだったので、これ以上大きなプログラムファイルは実行できません。従って、今回作った FACTOR-F2 は、fx-5800P での最速素因数分解プログラム だと、ここでは言い切ってしまいます。

全く異なるスーパーロジックが、将来見つかるかも知れませんが、そのときが楽しみです!




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


 


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

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

関連記事

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

fx-5800P 素因数分解 - 高速化

追記修正 2020/05/25
バグフィックス:2021/01/02


[2020/01/24]
ソースコード表示を追加し、C.Basicでの実行例の説明を追加しました。
[2020/05/25] 動作可能モデルの記述を更新しました。
[2021/01/02] FACTOR-F1 の終了時に配列変数を解放しない問題を修正しました。

今回は、fx-5800P の素因数分解プログラムの高速化の話題です。

素因数分解の一般的な方法は、"エラストテレスのふるい" と言われるものです。最初に入力した数 N を小さい順に素数で割り算を繰り返す方法です。最大の素因数は N の平方根以下の整数なので、平方根以下の整数を対象に2と3以上の奇数で割り算を行う方法で fx-5800P での素因数分解プログラムを作っています。
⇒ fx-5800P 素因数分解 - バグ修正と表示変更

さらに高速化する方法は無いものかと、色々と考えたり、試したりしていました。
例えば Casio 関数電卓の素因数分解 など。



最速の素因数分解プログラム

最近、目からうろこの高速化を達成した記事を見つけました。
A fast prime factorizing program for Casio fx-5800P 
このトピックで、作者の slugrustle 様 は、2つのプログラムを公開されています。いずれもプログラム名は FACTOR です。
オリジナルは、上のサイトをご覧ください。

これらには、面白い工夫がなされています。その部分には手を付けず、表示やユーザーインターフェースの不具合(と私が思うだけですが...)を解消するために、チョット変更しました。


1本目のプログラムの変更版:
結果の表示を 3^2 と乗数を表示し、List にも乗数の結果が FREQ に反映するように変更しました。
FACTOR-M1 のダウンロード

FACTOR-M1_1 FACTOR-M1_2 
FACTOR-M1 の結果出力 - 左: 乗数表示、- 右: [MODE] [3] で現れる List表示


2本目のプログラムの変更版:
オリジナルプログラムでは、結果表示画面を、複数ページで切り替えて自由に見られるようになっています。[EXE] [▲] [▶] [+] で次のページを表示、[(ー)] [▼] [◀] で前のページを表示、[EXIT] [DEL] でプログラムを終了するようになっています。計算が高速化しているだけでなく、結果表示も良くなっています。

このキーの使い方がチョット馴染まないので、[▼] で次のページ、[▲] で前のページ、[+] は使えないようにし、指定以外のキーを押した時の誤動作を抑制するように修正しました。時間をかけて計算できた結果が、誤動作で見えなくなるのは嫌ですから...
さらに、オリジナルはキーを軽く押しても応答せず長押しが必要、つまり応答がとても悪いので、キー入力待ちを最小のループにして応答を十分高速にしました。軽くキーを1回押すだけで、チョット待ちますが必ず画面が変わります。
またオリジナルでは結果表示一覧で素因数として 1 が表示されますが、1 は素数ではないので、素因数として 1 が表示されないように修正しました。
FACTOR-F1 のダウンロード [2021/01/02 バグフィックス]
ソースコードはこのページの一番下に掲載

FACTOR-F1_1  FACTOR-F1_2 
FACTOR-F1 の結果表示 - 全結果を画面切り替えで確認、左: 2/1ページ、右: 2/2ページ


比較のための以前作った PRIME DECOMP:
PRIME DECOMP のダウンロード

Prime_Decomp_2 Prime_Decomp_3 


上記でダウンロードしたZIPファイルには、それぞれ CCL ファイルと TEXT ファイルが含まれています。CCL ファイルは CcLinker を使って fx-5800P に転送できます。或いは、下のリンクからテキストファイルを参考にしてください。



計算時間の比較

先ずは、fx-5800P でどのくらい高速化されたかの結果を示します。

PRIME DECOMP
ソースコード
FACTOR-M1
ソースコード
FACTOR-F1
ソース (メインルーチン)
ソース (サブルーチン)
123,456,789
= 32 x 3607 x 3803
170 秒60 秒
3 倍高速化
42 秒
4 倍高速化
6,666,666,667
= 19 x 1627 x 215659
77 秒27 秒
3 倍高速化
20 秒
4 倍高速化
7,849,516,203
= 32 x 9811 x 88897
458 秒165 秒
3 倍高速化
111 秒
4 倍高速化

1本目の FACTOR-M1 で3倍高速化、さらに2本目の FACTOR-F1 は4倍高速化されていることが分かります。

素因数分解は、与えられた数を小さい数から順に割ってゆく時、その操作の回数を減らせば、高速化に繋がります。
PRIME DECOMP では入力した数に、先ず平方根をとって一気に探査範囲を狭め、2と3以上の奇数で小さい方から順に割り算してゆく作戦です。

一方で、理想的なのは、小さい素数から素数だけで順に割り算してゆくことです。それには素数リストが必要ですが、それがあれば苦労しません。素数を算出する計算式などありません。

さて、slugursite様の工夫は、高い確率で素数を見つけるだけでなく、割り算する候補 (例えば、2 や 3 だけでなく、一旦割り算で使った素数の倍数) を効果的にふるい分ける手法にあります。そして、最初の FACTOR-M1 よりも 次の FACTOR-F1 の方が、素数を見つける確率が高くなっているので、さらに高速化されています。



最速プログラムでの工夫 [2019/07/31]

読者のまつ様から、高速プログラムの考え方をご説明頂きました。私はこれに大変納得しましたので、それを掲載致します。以前の記述は撤回させて頂きます。

素因数分解プログラムで通常行われている割り算では,「2,および,3以上の奇数」を割る数としています。
これですと,ご存知のように,例えば3で割り切った後に9でも割るという無駄が出てしまいます。
FACTOR-M1は,「2, 3, 3より大きい3の倍数を除く奇数」を割る数としており,3で割ったあと9や15で割ることはないようにしています。

3より大きい3の倍数を除く奇数について考えてみます。

まず,3より大きい3の倍数でない整数は次の(1),(2)のどちらかです。
 3m+1 (1)
 3m+2 (2)
 (m>=1)

次に(1),(2)が奇数となる式をそれぞれ求めます。

(1)は (2m+1)+m と変形できます。2m+1 は奇数ですから,(1)が奇数であるためには m が偶数である必要があります。そこで m=2n (n>=1) とおけば,(1)は 6n+1 となります。

(2)は 2(m+1)+m と変形できます。2(m+1) は偶数ですから,(2)が奇数であるためには m が奇数である必要があります。そこで m=2n+1 (n>=1) とおけば,(2)は 6n+5 となります。

5とこれらの式を並べ,さらに,隣り合う式の差も書き加えると次のようになります。(n=1とします)
式の並び隣り合う式の差
52
6n + 14
6n + 52
6(n+1) + 14
6(n+1) + 52
6(n+2) + 14
6(n+2) + 52
:
:
:
:
このような訳で,2, 4, 2, 4, ... と加算していると思われます。
この繰り返しは,6n+1 および 6n+5 の式からも分かるように,2と3の最小公倍数6を周期としています。

FACTOR-F1は,これを拡張して,割る数として
 奇数,かつ,3の倍数でない,かつ,5の倍数でない,かつ,7の倍数でない整数
を順番に求めていく方法をとっていると思われます。
2,3,5,7の最小公倍数は210ですから,隣り合う割る数の差(2,4,6,8など)の並びは210が1周期です。
FACTOR-F1の場合は,13+210n〜13+210(n+1)-1 [n>=0]の範囲で,2,3,5,7のいずれの倍数でもない整数を並べて,隣り合う整数の差をリストにしていると思われます。

ちなみに,13〜222の210個の整数のうち,
 奇数,かつ,3の倍数でない,かつ,5の倍数でない,かつ,7の倍数でない整数
の個数は,FACTOR-F1の「While 1」の下にある
 B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1
のパターンの行数と同じ48個です。

48個となる理由は次の通りです。

まず,2,3,5,7の倍数に関わるそれぞれの個数を求めます。

2の倍数の個数=210/2=105
3の倍数の個数=210/3= 70
5の倍数の個数=210/5= 42
7の倍数の個数=210/7= 30
 
2と3の公倍数の個数= 6の倍数の個数=210/ 6=35
2と5の公倍数の個数=10の倍数の個数=210/10=21
2と7の公倍数の個数=14の倍数の個数=210/14=15
3と5の公倍数の個数=15の倍数の個数=210/15=14
3と7の公倍数の個数=21の倍数の個数=210/21=10
5と7の公倍数の個数=35の倍数の個数=210/35= 6
 
2,3,5の公倍数の個数= 30の倍数の個数=210/ 30=7
2,3,7の公倍数の個数= 42の倍数の個数=210/ 42=5
2,5,7の公倍数の個数= 70の倍数の個数=210/ 70=3
3,5,7の公倍数の個数=105の倍数の個数=210/105=2
 
2,3,5,7の公倍数210の個数=210/210=1

重複を考慮すると,
2,3,5,7のいずれかの倍数の個数
=(105+70+42+30)-(35+21+15+14+10+6)+(7+5+3+2)-1
=162

従って,2,3,5,7のうちどの倍数でもない整数の個数は,
 210-162=48
で 48個となります。


素因数分解の正しい動作を検証

この作者は自分のプログラムを検証するテストプログラムまで作って、ソースコード (C++) を公開しています。fx-5800P 用なので、素因数分解する数は最大10桁と決まっています。この条件下でアルゴリズムの正しさを検証しています。

検証プログラムのソースコードが公開されています。そこで Visual Studio 2019 Community でビルドしました。


 FACTOR-F1 のテストプログラム Factor.exe のダウンロード [2019/08/28 リンクを修正]

コマンドプロンプトで、Factor.exe のあるデイレクトリに移動し、そこで

 Factor 1000 50000 4

と入力してエンターキーで実行すると、1000 から 50000まで 4 刻みで入力を変化させて FACTOR-F1 を実行した結果を一気に連続して自動実行してくれます。そして、結果が素数がどうか判定し、素数でないものが出てくるとエラーを出し、素数であれば実行を継続します。正常終了すれば、正しく素因数分解が実行されたことになります。

factor_1
正常終了しているので、1000 から 50000 までの素因数分解は問題ないことが検証されました。


fx-5800P 用のプログラムなので、入力値は 1 ~ 9,999,999,999 (10桁) の範囲なので、完璧にテストするには、

 Factor 1 9999999999 1

とすれば良いのですが、試しに私のPCだと、1晩で150億回分の検査が済みました。 10桁に相当する (1000億 - 1) 個全部のテストは、夜のみ終夜運転で計算させるとして1週間程度必要になりそうです。

factor_2
1 ~ 9,999,999,999 までのテスト中

テストが正常終了すれば、このアルゴリズムが正しいことが検証されます。但し、他のパラメータ設定でも正しい組み合わせは有りそうです。



グラフ関数電卓用に移植 [2020/05/25 更新]

FACTOR-F1 をグラフ関数電卓用に移植しました。素因数分解の計算部分は変更の余地がありませんが、結果表示は7行全部を使うように変更しました。

グラフ関数電卓用 FactorG のダウンロード [2021/01/02 バグフィックス]
  バグフィックス:終了時に行列解放しない点を修正しました。

FactorG 
FactorG の結果表示

ここで作成したプログラムは、Casio Basic が搭載されたグラフ関数電卓で動作すると思われます。
カシオが過去に発売したグラフ関数電卓全てを調べていませんが、おそらく 1995年発売のフランス専用モデル GRAPH20、そして1996年発売の世界モデル fx-7400G 以降のモデルでは、このプログラムが動作すると思われます。 

実際に動作確認したモデル (若干の手直し移植を含む)
 ・CFX-9850G (若干の手直し、プログラムダウンロード)
 ・CFX-9850GC PLUS (若干の手直し、プログラムダウンロード)
 ・fx-9860G / fx-9860G Slim (そのまま動作)
 ・fx-9860GIIシリーズ - SH3/SH4A、SDモデル (そのまま動作)
 ・fx-CGシリーズ - CG10/CG20/CG50 (そのまま動作)
 ・fx-9750GIII / fx-9860GIII (そのまま動作)
※ これらは純正Casio Basic での動作

なお、上の画面は、fx-CG50 にインストールした アドインCasio Basic  - C.Basic for CG で実行した画面です。C.Basic は純正Casio Basic のほぼ上位互換なので、グラフ関数電卓用 FactorG.g3m がそのまま実行できます。C.Basic は純正Casio Basic よりもかなり高速に動作するので、上記の例だと一瞬で結果が表示されます。
アドインCasio Basic - トップページ



Factor-F1 (fx-5800P用) のソースコード

FACTOR-F1 – fx-5800P code
0→DimZ↵
22→DimZ↵
"NUMBER"?→F↵
If F<1 Or F≧1x₁₀10↵
Then "NUMBER□MUST□BE□□≧1□ And <1x₁₀10"↵
Stop↵
IfEnd↵
If F≠Int(F)↵
Then "NUMBER□MUST□BE□□AN□INTEGER"↵
Stop↵
IfEnd↵
For 1→E To 22↵
0→Z[E]↵
Next↵
0→Z[1]↵
0→Z[12]↵
0→E↵
F→A↵

Int(√(A))→C↵
2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
3→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
5→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
7→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
11→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵

While 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+8→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+8→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+6→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+4→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+10→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+2→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
B+10→B:A÷B→D:Frac(D)=0⇒Prog "WFSUB":B>C⇒Goto 1↵
WhileEnd↵

Lbl 1↵
If A>1↵
Then Isz E↵
A→Z[E]↵
1→A↵
1→Z[E+11]↵
IfEnd↵
Int(E÷3)→D↵
E-3xD>0⇒Isz D↵
1→C↵

Lbl 2↵
Cls↵
Locate 1,1,F↵
Locate 12,1,C↵
Locate 13,1,":"↵
Locate 14,1,D↵
3x(C-1)+1→B↵
Locate 1,2,Z[B]↵
Locate 11,2,"^("↵
Locate 13,2,Z[B+11]↵
Locate 16,2,")"↵
If B+1≦E↵
Then Locate 1,3,Z[B+1]↵
Locate 11,3,"^("↵
Locate 13,3,Z[B+12]↵
Locate 16,3,")"↵
IfEnd↵
If B+2≦E↵
Then Locate 1,4,Z[B+2]↵
Locate 11,4,"^("↵
Locate 13,4,Z[B+13]↵
Locate 16,4,")"↵
IfEnd↵

Do↵
Getkey→K↵
LpWhile K=0↵

0→M↵
If K=34 Or K=73↵
Then 1→M↵
Else If K=86 Or K=85 Or K=47↵
Then 2→M↵
Else If K=83 Or K=84 Or K=57↵
Then 3→M↵
Else Goto 2↵
IfEnd:IfEnd↵
IfEnd↵

If M=1↵
Then Cls↵
"DONE"↵
Else If M=2↵
Then Isz C↵
C>D⇒1→C↵
Goto 2↵
Else If M=3↵
Then C-1→C↵
C<1⇒D→C↵
Goto 2↵
IfEnd:IfEnd↵
IfEnd↵

0→DimZ↵



WFSUB – fx-5800P code

E+1→E↵
B→Z[E]↵
Do↵
D→A↵
Z[E+11]+1→Z[E+11]↵
A÷B→D↵
LpWhile Frac(D)=0↵
Int(√(A))→C↵
Return↵





今回は、slugrustle 様の Universal Casio Forum への投稿プログラムの解説記事になってしまいましたが、私としては十分楽しませてもらったので、記事にして残そうと思いました。



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


 


keywords: プログラム関数電卓、fx-5800P、素因数分解、プログラミング、Casio Basic

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


関連記事

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

謹賀新年2021年

COW 
 
新年明けまして、おめでとうございます。

昨年は新型コロナ肺炎ウィルスに世界中が振り回されましたが、
今年は少しでも前向きで明るい気持ちを
持ち続けたいと思います。

カシオのプログラム電卓の Python モードが、
今年はさらにバージョンアップされるでしょう!

北米市場で圧倒的なコストパフォーマンスの fx-9750GIII を
今年は国内で販売してもらいたいものです。

fx-5800P の後継モデルはどうなるのでしょうか?

当ブログでは引き続き Casio Basic に光を当て続けながら、
Casio Python を調べてゆきたいと思います。

丑 
令和3年 元旦
Krtyski (やす)



関連記事

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

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

やす (Krtyski)

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


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

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

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


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

ブロとも申請フォーム

この人とブロともになる

QRコード
QR