プレイ日記
おちゃめ ochame_nako
最近電卓を作る人が多く見かけますが、電卓を制作のときによく使われるであろうSTR$を使用していていきなり「1.23457e+08」とか表示されて「変な表示になった」とか思ったことがある初心者も多いと思います。 そこでSTR$使用時の注意点や対処方法などを書いておきます。初心者だけではなく中上級者も参考になると思います。
16そうだね
プレイ済み
返信[1]
親投稿
おちゃめ ochame_nako
知っての通りSTR$は数値を文字列に変換する関数です。 ただし、実数型(普通の数値変数)の数値をSTR$を使って変換すると有効桁数が6桁に丸められるというのを知っておく必要があります。 プチコン3号の実数型は2進数で52桁分、10進数だと16桁弱の有効桁数がありますが、STR$を使えばそれが6桁になるというわけです。 例えばA=123456789という9桁の整数はSTR$(A)とすると「1.23457e+08」になります。 これはどういう意味かというと「1.23457×10の8乗」という意味です。 1.23457に10の8乗(=1億)を掛けた123457000のことを示します。 これをVALを使いVAL("1.23457e+08")としても元の123456789という数値には戻りません。 123456789という数値がSTR$を使うことで123457000という値に変化するわけです。
0そうだね
プレイ済み
返信[2]
親投稿
おちゃめ ochame_nako
STR$を使えば有効数字が6桁になるということで6桁までの整数ならば何ら心配は要りません。 しかし、最大6桁の電卓というのも心もとないものです。 実はA%=123456789のように値を整数型の変数に入れている場合はSTR$(A%)で「123456789」という文字列にすることができます。 つまり、6桁を超えても変化しないということです。 整数専用の電卓であればこのように整数型変数を使うことで整数型の範囲内(-2147483648~2147483647)はSTR$で正しく文字列にすることができるということです。 「文字列化せずに普通に数値のまま表示すればいいのでは?」と思うかもしれないですが、その場合は最大でも小数第8位までしか表示できないという問題があるし、表示の整形をしにくいという問題があります。
0そうだね
プレイ済み
返信[3]
親投稿
おちゃめ ochame_nako
では、小数を含む実数型では文字列化をする際に6桁の壁は突破できないかというとそんなことはありません。 そういうときの心強い見方がFORMAT$です。 FORMAT$を使えば整数部、小数部ともに自由に設定した桁数で文字列化が可能です。 整数部に関しては指定していてもそれを超える桁数の場合は自動的に拡張されるため FORMAT$("%17.6f",A) として変数Aの値を整数10桁、小数6桁(小数点込みで17文字分確保)で表示するようにしてもAの値が1e10(100億)ならば11桁の数であるため自動的に整数部は11桁分に広がるというわけです。
0そうだね
プレイ済み
返信[4]
親投稿
おちゃめ ochame_nako
整数部は超えた分が自動的に拡張されるため桁揃えが必要でなければ FORMAT$("%.6f",A) として小数部の桁数のみ記述しても問題ありません。 ただし、FORMAT$は指数での表記ができないため ?FORMAT$("%.6f",POW(2,256)) などの絶対値が大きな数を表示したい場合は末尾に無駄にゼロが並ぶという点は注意する必要があります。 FORMAT$において整数部に関しては必要な場合に上記のように自動的に拡張されるのですが小数部に関しては指定した桁数の分だけしか表示できません。 ?FORMAT$("%.6f",1) では、1.000000と表示されるということです。 さらにあらかじめ指定した分しか表示ができないため?FORMAT$("%.6f",A)では小数第6位までしか表示できないということになります。
0そうだね
プレイ済み
返信[5]
親投稿
おちゃめ ochame_nako
そのため ?FORMAT$("%.6f",POW(2,-20)) は「0」と表示されます。 これが0にならないように必要な桁数だけ求めるためには対数などを使って表示桁数を調整するしかありません。 FORMAT$は「あらかじめ整数部○桁、小数部○桁で表示」と決めておくならば便利な関数ですが、小数部がその範囲で収まらない場合にうまく表示させるのは難しいということです。
0そうだね
プレイ済み
返信[6]
親投稿
おちゃめ ochame_nako
そこで登場するのが私の自作関数PSTR$です。 https://miiverse.nintendo.net/posts/AYIHAAAEAABEVRTp-ZVMIg このPSTR$は上記のSTR$とFORMAT$の欠点を埋めるために考え出したものです。 つまり、STR$の「丸められて値が変わってしまう」という欠点、FORMAT$の「桁数指定を調整するのが難しい、(絶対値が大きな数や小さい数は)無駄に0が羅列してしまう」という欠点を無くしたものです。 そして、何も考えなくてもA$=PSTR$(PI())でA$にはPI()を文字列化した値が入り、その状態でA=VAL(A$)とすればAにはPI()と全く同じ値が入るため扱いも非常に楽ということです。 FORMAT$でこれと同じことをするのは非常に大変でVALで正しく数値化できるのは絶対値が1e-81以上1e+99未満の数に限ります。
0そうだね
プレイ済み
返信[7]
親投稿
おちゃめ ochame_nako
PSTR$は仕様上「絶対値が1e+16以上の値」または「絶対値が1e-5未満の値」は指数表記にするようにしています。 これは分かりやすさを最優先しているためです。 FORMAT$ではPOW(2,256)などの大きな数を表示した場合には末尾に無駄な0が羅列することになりますが、PSTR$ではそれを避けるために「絶対値が1e+16以上の値」は指数表記にしています。 なぜ1e+16かというとプチコン3号の実数型の有効桁数が上記のように16桁弱しかないためです。 つまり、整数部が16桁を超えたら末尾に羅列する0は無駄になっていくため指数に切り替えて0を省略しているわけです。
0そうだね
プレイ済み
返信[8]
親投稿
おちゃめ ochame_nako
「絶対値が1e-5未満の値」が指数表記になるのは人間が瞬時に認識できるのは4桁までだからです。0.00001234のように小数点の横に0が4つ並んでいれば「4つ」と瞬時に認識できますが、0.0000001234と6つ並んでいる場合には「6つ」と瞬時に認識するのは難しいです。 それに加えて文字列化したときに無駄に桁数が増えるのを避けるためです。 1e-5に抑えることで最大時でも24桁に止まります。 PSTR$はセーブデータとして利用できる(SV=TRUEで使用可能)のですが、スペースを入れて25桁ちょうどとなるためまとめて1つにして保存しても25桁ごと区切ってVALで変換すれば元に戻せる(丸められず文字列化できるため)というメリットがあります。
0そうだね
プレイ済み
返信[9]
親投稿
おちゃめ ochame_nako
ちなみにSV=TRUEとしたときの25桁というのは通常表示であれば横に2つ分、WIDTH 16時でちょうと1つ分ということで表示するにも都合が良い値です。 PSTR$ ver.2.0においてver.1.0から仕様変更したのはこのような意味があるためです。 では、電卓を作るのにPSTR$を使えば万全かというと実はそうとは言えないのです。 というのもあまりに正確すぎるためです。
0そうだね
プレイ済み
返信[10]
親投稿
おちゃめ ochame_nako
本来は内部で丸められて表示されている0.1みたいな数も正確に0.10000000000000001と表示されるためです。(10進数で0.10000000000000001と記録されているわけではなく0.1は2進数では循環小数となってしまうため52桁で丸められた2進数を10進数に変換した結果がそうなるというだけ) これが示すようにプチコン3号の「0.1」は「0.1より少し大きな数」であるため0.1を100回足しても10ちょうどにはならないけどPSTR$ならばそれも目視確認が可能であるということです。 PSTR$は正確すぎるため感覚とずれる部分があるため電卓として使用するのであれば「STR$ほど極端には丸められないけどPSTR$ほど極端に正確ではない文字列化を行える自作関数」を作るというのがベターかもしれませんね。
0そうだね
プレイ済み
返信[11]
親投稿
%ってそんな使い方だったんですね…
1そうだね
プレイ済み
返信[12]
親投稿
☆Tatsukin★ tatu_kin1192
僕が作っている電卓はSTR$とか使ってませんけどね…。 数値のままです。 なので、桁が多くなると、正確な値じゃなくなります。 なので、僕は、「この電卓が出す数値は、大体のもので、正確な値ではありません。なので、計算問題などで使わないで下さい。」と表記しています。 お子さんが宿題とかで電卓を使わないように配慮している感じです。 (嘘です。そんなこと書いてません。今ここで考えたのは内緒です。)
0そうだね
プレイ済み
返信[13]
親投稿
ちょっと関係無くなりますが、eって乗っていみだったんだてすね
0そうだね
プレイ済み
返信[14]
親投稿
おちゃめ ochame_nako
オワたず(^p^)ゝさんへ %の有無(実数型と整数型)は計算できる値の範囲が異なるだけではなくSTR$のように使用する関数や命令によっては挙動さえも異なる場合もあるという例にすぎません。 ☆Tatsukin★さんへ みんながSTR$を使っているからといって無理にそれに合わせる必要はありません。 自分のプログラムならば自分が作りたいように作るのも正解ですね。 ☆くもき☆さんへ 「指数」を英語表記した「exponent」の略でプチコン3号を始めとする多くの環境では10の何乗という意味で使用しています。
0そうだね
プレイ済み