HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0606
はりー小数の比較について5解決


はりー

リンク

2016/6/6(Mon) 22:47:14|NO.75755


dialog ((1.00-0.95)==0.05)

これを実行して、なぜ1が帰ってこないのでしょうか?



この記事に返信する


motchy

リンク

2016/6/6(Mon) 23:13:13|NO.75757

厳密に (1.00-0.95)==0.05 ではないからです。

因みに、(1.00-0.75==0.25) なんかはセーフです。我々の計算機がどういう仕組みで数値を記憶しているのか調べてみると良いでしょう。面白いですよ。



GENKI

リンク

2016/6/6(Mon) 23:26:40|NO.75759

実数の計算結果がイコールで完全一致することはごく稀です。
とりあえず提示された条件でなぜイコールにならないのか確認できるスクリプトを書いてみました。

mes strf("%1.20f", 1.00-0.95) mes strf("%1.20f", 0.05) ;デバッグウィンドウでも見れるけど、変数の中をそのまま16進数表記してみる。 a = 1.00-0.95 y = ginfo_cy repeat 8 pos cnt*20, y mes strf("%02X", peek(a, 7-cnt)) loop a = 0.05 y = ginfo_cy repeat 8 pos cnt*20, y mes strf("%02X", peek(a, 7-cnt)) loop

そもそも実数の全てを64bit程度で表現できるわけがなく…そいういうものだと思ってください。(例えば円周率なんかを思ってください。)
プログラムで実数を使うときは以上、以下なんかを使うといいですよ。
どうしても制度が必要な場合は整数を使います。
例:
dialog ((100-95)==5) ;×100して計算する。



Velgail

リンク

2016/6/7(Tue) 06:18:57|NO.75762

>どうしても制度が必要な場合は整数を使います。
整数に変換した時点で精度が落ちてるので、精度を維持したとはいえません。

正しくやるのであれば、許容する誤差を明確にしてあげれば良いです。
精度自体は多少落ちますが、整数変換より圧倒的に優位です。
例えば、「誤差0.0000001以内なら等しいとする」という解釈であれば、

dialog (absf((1.00-0.95)-0.05)<0.0000001) //すなわち、比較するAとBの差分の絶対値を取って、その差が許容誤差以内(A≒B)であるか?
のようにやればよいでしょう。
ただ、計算機イプシロンのような値を上手く使うほうがより良い結果が得やすいかも?
そこら辺は好みと技量に合わせて定義してください。小さすぎる値は不具合のもとですが。



USER

リンク

2016/6/9(Thu) 19:55:38|NO.75802

πならわかるような気がしますが0.05のような数字でもう動きが怪しくなるんですね
いやはや驚きです



はりー

リンク

2016/6/9(Thu) 22:17:34|NO.75809

理解出来ました、皆様ありがとうございます。

最終的に100倍してやる形に落ち着きました。



ONION software Copyright 1997-2021(c) All rights reserved.