- 締切済み
-2.15 + 2.11 = -0.04 ?
以前に「-2.18+2.11=-7.00000000000003E-02 ?」で質問させて頂きました。 その時に、浮動小数点型のため、必ず誤差があるとの回答をもらいました。 今回は、前回と同様にVBScriptにて計算をしたのですが、誤差が出ていないように見えます。 誤差が出る時と出ない時の条件のようなものがあるのでしょうか? それはどのような条件なのでしょうか? 使用したコードは以下のとおりです。 Dim a Dim b a = -2.15 b = 2.11 MsgBox (a + b) (前回は「-2.15」の部分を「-2.18」としていました。) ご存知の方がいらっしゃいましたら、よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
誤解されているようですが、固定小数点でも誤差は出ますよ 今回の問題は、 10進数→2進数の変換の際に割り切れない数があるってことです
前回も解答した者です >必ず誤差があるとの回答をもらいました。 ではなく、厳密には、誤差が出る場合がある。です。 >誤差が出ていないように見えます。 そう見えるだけで、誤差は出ています。 誤差が出ていても、その誤差が切り捨てられて、結果誤差が無いように見える場合も有ります。 今回の数式も誤差はありますよ。 >誤差が出る時と出ない時の条件のようなものがあるのでしょうか? 厳密な条件を知るには、コンピュータの内部表現や計算順序を詳しく知る必要が有り、不可能に近いと思います。 誤差が出る可能性を考慮して、必ずFormatNumberやRound関数など使うようにしましょう。
お礼
今まで何とも無かった計算式の部分で、突然指数表記が出てきてびっくりしてしまいました。 色々な数値を入れて試したのですが、指数表記になる時とならない時の条件がわからす、苦しんでいます。 やっぱり、厳密な条件を知るのは不可能なんですね。 ありがとうございました。
- neKo_deux
- ベストアンサー率44% (5541/12319)
> 必ず誤差があるとの回答をもらいました。 ただし、整数やきちんとIEEE754で表現できるものは除きます。 今回の場合も誤差は出ているが、誤差の範囲が倍精度浮動小数で表せる15桁より小さいので、15桁以下の値を切り捨てた結果としてそういう風に見えています。 丸め誤差は、計算のときに出るのではなく、 > a = -2.15 > b = 2.11 の時点、数値をコンピュータのメモリに格納した際に発生します。 逆に、a=-2.15000000000001とか-2.150000000000005にすると、0.00…001の誤差が出るはずなのに、出たり出なかったりすると思います。 -- 例えると、 1ドル=118.07円で、手数料などは考えずに、円建てとドル建てで30000円-20000円の計算をします。 20000円=20000/118.07=169.3910392…=169ドル39セント 30000円=30000/118.07=254.0865588…=254ドル08セント 30000円-20000円=10000円 254ドル08セント-169ドル39セント=84ドル69セント=84.69×118.07=9999.3483=9999円34銭=9999円 1円どこかに行っちゃいました。 最初にドル建てに直した時点で、1セント以下の金額って無いので、丸め誤差が出ます。 最後に円建てに直す際にも、1銭以下の金額は無いので、丸め誤差が出ます。 とか? ※この場合は誤差の出る方向がそれぞれ逆のハズなので、相殺の結果マイナスになってるハズですが。
お礼
そうなんですね。計算結果だけではなく、変数に値を入れた時から誤差との戦いが始まっているんですね。 「例え」の円建てとドル建ての話、参考になりました。 ありがとうございました。
そもそも浮動小数点では2.15をを誤差なく保持できていません。 2.15は2.14965820625に誤差が出ています(2進15桁くらいでしか計算していないので桁を増やせばもっと2.15に近くなります) このように浮動小数点を2進で表した誤差が、足し算の誤差にも現れます。
お礼
なんだか浮動小数点て「使えないなぁ」と思ってしまいますね。 固定小数点だと、計算に時間がかかると聞いたことがあります。 でも誤差が出ないのなら、そっちの方が良いですね。 ありがとうございました。
- ffffffff
- ベストアンサー率35% (68/194)
誤差が無いように見えるだけで、以前と同じように表記すると「-2.15+2.11=-4.00000000000000E-02」ということになり、最後の"0"以降に誤差を含んでいます。 浮動小数点型は、こういうものだと認識したほうが宜しいです。 Dim a as Float とか、 Dim a as Double とか、 浮動小数点型の使用バイト数を変化させると、"00000000000000E-02" の数値(誤差?)が変化する可能性があります。
お礼
素早い回答ありがとうございました。 やはり他の方も言われていますが、誤差はあるが見えない(場合がある)と認識して計算式を組み立てるしかなさそうですね。
お礼
おや?私の勘違いでしたか・・・ てっきり浮動小数点の場合の問題だと思っていました。 指摘して頂いて助かりました。 つまり整数であれば問題なし、そして小数でも有効桁数内できっちり表記できれば問題なしという事ですね。