【解決済】【RGSS3】命中率の計算式

キリナ
記事: 4
登録日時: 2020年9月08日(火) 21:52

【解決済】【RGSS3】命中率の計算式

投稿記事by キリナ » 2022年2月18日(金) 00:46

はじめまして。
誰か力を貸してくれると助かります。

キャラクターのステータスとして命中率を100%に設定したとします。
装備品の特徴に『[命中率]-5%』をつけたものを2つ装備した場合、
想定としては100%-5%-5%で90%にしたいのですが、なぜか89%となります。
1.00*0.95*0.95として計算しても90%になりそうなものですが……。

おそらくどこかで小数点の切り捨てか何かが行われているのだろうとは思いますが、
該当箇所が私ではわかりませんでした。
修正方法がわかる方はいますでしょうか? 
最後に編集したユーザー キリナ on 2022年2月20日(日) 04:51 [ 編集 1 回目 ]

TOMO
記事: 343
登録日時: 2015年11月16日(月) 20:12
連絡を取る:

Re: 【RGSS3】命中率の計算式

投稿記事by TOMO » 2022年2月18日(金) 02:45

元々、小数の計算が偶にズレるのは仕様です

コード: 全て選択

((1.0 - 0.05 - 0.05) * 100).round
とすれば多分90%になります
キリナ
記事: 4
登録日時: 2020年9月08日(火) 21:52

Re: 【RGSS3】命中率の計算式

投稿記事by キリナ » 2022年2月19日(土) 17:52

おそらくずれることがあるのは仕様(元からのバグ)だろうというのは察していますが、
どこかで命中率を計算しているはずで、その命中率を計算しているメソッドが分かれば対処方法も検討できるかなぁと考えています。

修正が必要な該当箇所が私には読み解けていない為、
修正方法は現状では二の次となっています。
修正方法ではなく、ここを書き換えたら直せるという情報があれば助かります。
(式の修正だけではどこを書き換えるのか分からない為、現状では解決に至れません。申し訳ございません)
名無し蛙
記事: 304
登録日時: 2015年11月23日(月) 02:46

Re: 【RGSS3】命中率の計算式

投稿記事by 名無し蛙 » 2022年2月19日(土) 21:47

どこで小数点の切り捨てをしているか、と言われたら「していません」が答えですかね?

キリナ さんが書きました:想定としては100%-5%-5%で90%にしたいのですが、なぜか89%となります。
これはどうやって確認しているのでしょうか
VXAceのデフォルトでは命中率を表示する機構はないはずです、よね?
それを確認する為のスクリプト素材内で小数点(第三位以下)を切り捨てて表示しているんだと思いますよ

メニューバー>「ゲーム」>「コンソールの表示」にチェックを入れて
適当なイベントコマンド>スクリプトから

コード: 全て選択

p $game_actors[アクターid].hit
と打ち込んでください
イベント実行時にコンソール上に0.8999999999と表示されるはずです
これがゲーム内で使用される正確な命中率の値です

では何故、本来0.9として扱われるべき値が0.8999999999に変換されるのか?
これはツクールの問題ではなければRubyの問題でもなくコンピュータの数値表現上での仕様です。
一言で言えば浮動小数点数の丸め誤差が作用している、ですけど
どちらも本来は情報工学の講義で習うような事なので詳細を知りたければ自分で調べてください。
自分もそれほど詳しくないですけどトピック内で説明し切れる事ではないです。
1/3=0.3333333....になるように、キリが悪い計算を繰り返すにつれて情報が欠落するのは仕方がない事です。
同様に浮動小数点数形式では0.95-0.05は非常にキリが悪くなる演算にあたります。
一般的なプログラミング言語では0.95-0.05という計算をすると0.89999999になってしまう、という認識でも良いです。

話を戻すと命中率の表示時に切り捨て処理(.to_iか.floor)が使われてるはずなので
TOMO氏の言う通り.round(四捨五入)か.ceil(切り上げ)を使って調整するのが適切だと思いますね。

追記で
どこで設定された命中率の合計処理をしているかと言えば
hitを参照する度に設定された特徴オブジェクトから
「追加能力値」「命中率」を抜き出して全ての値を合計・取得しています。
hit<xparam<features_sum内の処理ですね
キリナ
記事: 4
登録日時: 2020年9月08日(火) 21:52

Re: 【RGSS3】命中率の計算式

投稿記事by キリナ » 2022年2月20日(日) 04:50

返信ありがとうございます。

>これはどうやって確認しているのでしょうか
様々な場所で公開されているスクリプトを参考に改変して表示していました。
装備画面のステータス表示画面やショップの変動画面が主な表示場所です。

普段の言語では任意精度型で計算する癖がついていた為、浮動小数点数の誤差について失念していました。
(あと理解が浅い為、少数2桁くらいの簡単な計算で出るとも思っていませんでした)

コード: 全て選択

(features_with_id(code, id).inject(0.0) {|r, ft| r += ft.value }).round(2)

上記で試した結果、
features_sum内で四捨五入をした結果、テストパターン上では計算がおかしな表示になることはなくなりました。

その後、改めて表示方法を見直した際にステータスの表示時に2桁のtruncateが使われていた為、roundに変更することでも同様の結果は得られました。

私が色々勘違いしていた為、お騒がせ致しました。
お二人とも、ありがとうございます。解決とさせていただきます。

“VX / Ace:質問” へ戻る