dポイントプレゼントキャンペーン実施中!

sub test()

Data = 1.03 - 1.001


filepath = "C:\test.txt"

Open filepath For Output As #1

Print #1, Trim(Data)

Close #1
end sub

というsubをVBAで実行します。
すると
2.90000000000001E-02
という値が出力されます。

1.03 - 1.001
は0.029のはずなのに、0.00000000000001E-02 ずれるのはなぜか教えてください。

これを指数ではなく標準形式で出力したいのですが

Print #1, Trim(Format(Data, "#.##"))

の方法だと桁数が分かっている場合には良いのですが
桁数が未知の場合にはどうしたら良いですか?
Print #1, Trim(Format(Data, "#.###############################"))

のようにどんな値が来ても良いように大きめに桁数を取っておくしかないですか?

A 回答 (2件)

こんにちは。



私は、しばらくVBAも離れていたので、もう一度、復習を兼ねて総ざらえしてみました。

すでに#1様がご説明がありましたが、統計的にみて、小数点演算の約7割ぐらいに、浮動小数点誤差が発生しますので、小数点(時間計算を含む)は、それなりの方策を取らなくてはなりません。これは、VB6のマニュアルには載っているのですが、Excel VBAでは、私自身は、あまり見たことがありません。しかし、表計算の表の部分でも、同じことが起こっています。

概ね、VBプログラミングで教わる方法は、

固定小数点法, 整数変換法 の二点だと思います

固定小数点法というのは、出てきた小数点の数字をそのまま扱うことです。

Currency やCDec などの十進数計算もこの部類に入ります。
計算スピードも速いそうです。

a = 1.03: b = 1.001

mData = CCur(a) - CCur(b)
mData = CDec(a) - CDec(b)

mData = Format(a - b, "0.000") '←?

また、このような固定小数点法もあります。
mData = 1.03@ - 1.001 'リテラルに直接@を付けます。

整数変換法というのは、本来、整数値では誤差がでませんので、10の小数点の桁数を掛けて整数にします。しかし、そのまま、整数にすると間違うこともあるので、丸めます。

mData = (Int(a * 10 ^ 3 + 0.5) - Int(b * 10 ^ 3 + 0.5)) / 10 ^ 3
こんな計算です。Intは、負数の計算には使えませんので、Fix関数を用いることも可能です。

また、VBAには、ワークシート関数以外には、小数点を丸めるためのRound関数がありませんから、
このような方法になります。

http://dobon.net/vb/dotnet/beginner/floatingpoin …
http://support.microsoft.com/kb/214118/ja
    • good
    • 0

こんにちは。



> 1.03 - 1.001
> は0.029のはずなのに、0.00000000000001E-02 ずれるのはなぜか教えてください。
とりあえず、
【浮動小数点数 誤差】
のようなキーワードで検索すると、
たくさんの解説が見つかりますから、みてください。
簡単にいうと、二進数で小数点数を演算する以上は。
十進数との間に丸め誤差に代表される誤差が生じるのは必然です。

対策。

> Data = 1.03 - 1.001

 Data = CDec(1.03) - CDec(1.001)


> Print #1, Trim(Data)

 Print #1, CStr(Data)

のような対処で、Format()関数は使わなくても、
今回のケースでは、十分かと。

小数点数の演算を十進数として扱えば、
人間にとって普通の計算をして、お望みの答えが返ってきます。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!