Archiverse Internet Archive
投稿のみ 投稿と返信
前のページ(最近)
1101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121154
次のページ(過去)
返信[16]
親投稿
おちゃめ ochame_nako
(1)プチコン3号のLOG関数は常用対数(底が10の対数)を使って計算した場合に1e3(=1000)、1e6(=1000000)みたいに10の「3の倍数乗」の時は整数値が得られるはずなのに演算誤差で小数値になってしまい正しい桁数は求めることができません。 これはすでに上記の通りでLOGを使う限りは避けられないことなのでLOGを使わずに文字列操作のみで指数表記における指数部分(常用対数による演算を整数化したもの)と同等のことを行いそれで対応しました。
0そうだね
プレイ済み
返信[15]
親投稿
おちゃめ ochame_nako
これで、PSTR$の利便性が理解いただけたと思いますが、この大幅バージョンアップされたPSTR$は前バージョンのPSTR$から何が変わったのかを書いておきます。 (1)LOGの演算誤差によって発生していた誤動作の修正(要するにバグ修正) (2)桁揃えへの対応 (3)「-0」への対応 (4)非正規化数への対応 (5)infやnanへの対応 (1)~(5)を詳しく解説すると以下のような感じです。
0そうだね
プレイ済み
返信[14]
親投稿
おちゃめ ochame_nako
また何度も書きますが内部では2進数で表現されているため10で割って10倍しても元の数に戻る保証はできません。 A=小数を含む適当な数、B=A/10*10 とした時に「A=B」になるとは限らないのでそういう時にもPSTR$を使って表示すればなぜそうなるのかが分かります。 このようにPSTR$はセーブデータ作成時に限らず値の正確な表示が必要な場面で活用することができます。
0そうだね
プレイ済み
返信[13]
親投稿
おちゃめ ochame_nako
「0.1を100回足したら10になるようにしたい」という場合には私の自作関数PRを使用すると良いです。(PR関数は私の過去の投稿を参照) これは数値そのものを普通に表示した時の値と同じになるように丸める関数です。 VAR A,I WHILE A<10  INC I  A=PR(A+0.1)  ?I,A  WAIT 10 WEND ?PSTR$(A) ループを抜ける時ぴったり10になっていることが分かると思います。
0そうだね
プレイ済み
返信[12]
親投稿
おちゃめ ochame_nako
パッと見た感じだと原因を特定するのが困難な不具合ですが、これもPSTR$を使えば理由は一目瞭然で0.1を100回足した時点では10未満の数になっているためです。 VAR A,I WHILE A<10  INC I  A=A+0.1  ?I,PSTR$(A)  WAIT 10 WEND
0そうだね
プレイ済み
返信[11]
親投稿
おちゃめ ochame_nako
例えば次のプログラムを実行して分かるように0.1を100回足しても10未満の数になり、101回目にようやく10以上の数になります。 VAR A,I WHILE A<10  INC I  A=A+0.1  ?I,A  WAIT 10 WEND
0そうだね
プレイ済み
返信[10]
親投稿
おちゃめ ochame_nako
このPSTR$は誤差ゼロで数値を文字列に変換できるためセーブデータに使えるというだけではなく様々な利用方法が考えられます。 例えば「1000」という数字が何桁の数なのかFLOOR(LOG(1000,10))+1で求められますが、なぜか「3」と表示され「1000が3桁の数」になってしまいます。 これはPSTR$を使って表示すれば3.9999999999999996となっていてこれを整数化すれば4ではなく3になるのは一目瞭然になります。 また、プチコン3号の内部では数値はすべて2進数で表現されているので「0.1」でさえも正確に表現することはできません。(0.5や0.25のような2の累乗分の1ならば正確な表現は可能) したがって、小数を含む計算をした場合には予期しない不具合が発生する場合があります。 そのような場合は普通に変数の値を表示しても発見はできませんがPSTR$を使えば発見が可能です
0そうだね
プレイ済み
返信[9]
親投稿
おちゃめ ochame_nako
冒頭のサンプルの1番上の表示はA=PI()として表示の比較を行っています。 普通に表示すると小数第8位までに丸められてしまうため3.14159265となります。(小数第9位以下は普通に表示したら分からない) STR$で文字列化したものを表示すると3.14159となりますが、これをVALで数値化しても上記のように元の値には戻りません。 PSTR$では3.1415926535897931となり、これはVALで数値化した場合にはPI()の値と一致します。 3.141592653589793までが円周率の正しい値を示していてプチコン3号の実数型の有効桁数が16桁程度あることが分かると思います。(有効桁数は10進数だと16桁弱となる)
0そうだね
プレイ済み
返信[8]
親投稿
おちゃめ ochame_nako
また、プチコン3号で普通に数値を表示すると指数を使って表示されないため絶対値が大きな数字は桁数が多くなって非常に分かりづらいし、絶対値の小さな数字(5e-9未満)は0と表示されてしまいます。 絶対値が大きな数字や小さな数字は指数表記の方が分かりやすいし、数値化することを考えると文字列化を行っても100桁未満にすることが求められます。 「正確さ」と「分かりやすさ」の両方の要求に応えるのがこのPSTR$なのです。 公開キー【 NKADEE93 】、ファイル名「PSTR」です。
1そうだね
プレイ済み
返信[7]
親投稿
おちゃめ ochame_nako
これはプチコン3号のVAL関数は100桁以上の文字列を数値化すると0を返す仕様になっているためです。 そのためセーブデータとして使うためには有効桁数を含めて99桁以内になるような範囲の値に限られます、 つまり、VAL関数の制限の問題が発生するため「FORMAT$を使えば万全」というわけではないということです。
0そうだね
プレイ済み
返信[6]
親投稿
おちゃめ ochame_nako
FORMAT$はどこまでの桁数を得たいのかをあらかじめ指定しておく必要があります。プチコン3号の有効桁数を考えると小数第1位までの値(0.1単位で加減算した値)を正確に文字列化するには得るためにはFORMAT$では小数17位まで指定する必要があります。 どのような数値にも対応できるようにしたいならばFORMAT$("%309.324F",A)としてプチコン3号で扱える範囲内のすべての数値を表現できる桁数を指定しておけば良いです。ただし、これを表示すれば0が羅列して非常に分かりづらいです。 表示が分かりにくければ表示の際に数値化すれば良いと考える人もいるかもしれません。 では、PRINT VAL(FORMAT$("%309.324F",A))としてみてください。 するとAがどのような値であっても「0」と表示されます。
0そうだね
プレイ済み
返信[5]
親投稿
おちゃめ ochame_nako
ただし、プチコン3号の内部ではすべての数値は2進数で表現されています。 したがって、0.1でさえ循環小数となっているためAの値が小数第3位まであれば十分という場合であっても小数第3位までを文字列化すれば十分というわけではありません。 プチコン3号の有効桁数を考慮する必要があるためです。プチコン3号の有効桁数は52bit分あり、これは約15.6桁分の有効桁数になります。 ちなみに2進数で小数がどのように表現されるかはあらゆる数値(プチコン3号の実数型で扱うことができるすべての数値)を2進数に変換できる私の自作関数BIN64$を使いBIN64$(0.1)とすれば分かります。
1そうだね
プレイ済み
返信[4]
親投稿
おちゃめ ochame_nako
プチコン3号には文字列にする命令としてはSTR$の他にもFORMAT$が存在します。 Aの値が整数ならばFORMAT$("%10D",A)とすればAの値を10桁の文字列にすることができます。 小数を扱いたい場合はFORMAT$("%10.3F",A)とすればAの値を小数第3位まで文字列化することができます。
0そうだね
プレイ済み
返信[3]
親投稿
おちゃめ ochame_nako
文字列を数値に変換するにはVALを使いますが、A$=STR$(A)の時にVAL(A$)としても1234570という値になり本来の1234567という値には戻りません。 これだとセーブデータとして使うのには不安が残ります。 といっても100万未満の整数値しか扱わないならSTR$で問題ないし、STR$(A%)のように整数型変数を指定した場合には整数型で扱える-2147483648~+2147483647の範囲の整数ならば誤差無し(指数表示無し)で文字列化が可能です。 したがって、小数を扱いたいとか100億とか1兆とかの大きな数を扱いたいというのであれば問題があるというだけです。
0そうだね
プレイ済み
返信[2]
親投稿
おちゃめ ochame_nako
プチコン3号には数値を文字列に変換するSTR$関数が標準で存在しているのにこのような自作関数を作ったのはSTR$は文字列化する場合に値が丸められてしまう場合が多いからです。 例えばA=1234567の時にSTR$(A)は1.23457e+06となります。 これは1.23457×10の6乗という意味です。 指数を使わずに表記すれば1234570となります。 
0そうだね
プレイ済み
返信[1]
親投稿
おちゃめ ochame_nako
プログラムリストです。(公開キーは後述)
0そうだね
プレイ済み
プレイ日記
おちゃめ ochame_nako
数値を誤差ゼロで文字列に変換するPSTR$関数のver.2.0ができました。 PSTR$はセーブデータ作りやデバッグ用など様々な用途で活用できる便利な関数です。 PSTR$の詳しい使い方やSTR$、FORMAT$ではなぜダメなのかはコメントに書いているので、ぜひ参考にしてみてください。
14そうだね
プレイ済み
返信[15]
親投稿
おちゃめ ochame_nako
壊れる前に描いた音姫ちゃんのラクガキ絵
0そうだね
プレイ済み
返信[14]
親投稿
おちゃめ ochame_nako
トイレといえば、今日職場のトイレ(和式)にNew3DSを落としてしまい壊してしまいました。電源は入るもののボタン操作ができない(常にボタンが押されている状態になっている)ためプチコンは使えなくなりました。 これが和式ではなく様式だったらただの落下で済んだので助かったと思うと悲しいですが、していたのが大ではなく小だったのでウンこそ無かったけど不幸中の幸いといった感じです。
0そうだね
プレイ済み
返信[13]
親投稿
おちゃめ ochame_nako
うえこうさんへ トイレは関係ないですよ!?(笑) ヨッシーさんへ Lv5ならばなかなかだと思いますよ。 作った私でも最高でLv7です。(絶対音感のある人だとLv2桁は余裕かも)
1そうだね
プレイ済み