Home » いちばんやさしいExcel VBAの教本 » VBAで小数の計算が合わない?

浮動小数点数を使った計算について、拙著『いちばんやさしいExcel VBAの教本』のP.125のワンポイントで以下のように書きました。


小数の計算を行うと間違いが生じるのがパソコンの原則ですから、誤差を一切生じさせたくない場合には、いったん整数に変換する処理を入れることも検討しましょう。

入門書であるため詳細な解説は省略しましたが、意外と簡単な小数の計算で間違った値になります。

浮動小数点数の計算で間違える例

日々の生活の中で見かける、税込み金額から税抜き金額を計算するような場合でも、小数の計算を間違える様子を確認できます。

消費税率10%の商品で消費税込みの金額が110円のときに、消費税抜きの金額は100円であることは暗算でも計算できますが、浮動小数点数を使ってコンピューターに計算させると間違った値になってしまいます。


Sub sample_1()
 Debug.Print Int(110 / 1.1)
End Sub

上記のSubプロシージャを実行すると、イミディエイトウィンドウには「100」ではなく「99」が出力されます。

これはVBAだからというわけではありません。

例えばPython 3.8.0で、
  print(int(110/1.1))
というコードを実行しても、やはり「99」が出力されます。

110割る1.1が100でないことを確認する

まず「110 / 1.1」の結果が「100」でないことを確認しましょう。

以下のSubプロシージャを実行します。


Sub sample_2()
 Debug.Print (110 / 1.1) = 100
End Sub

「110/1.1」の結果と「100」が等しいかどうかを調べた結果を出力しているSubプロシージャで、実行すると、
  False
が出力されます。

この結果から「110 / 1.1」は「100」ではないことがわかります。

110 / 1.1が99.9999...であることの確認

「110 / 1.1」の結果が、いくつなのかを推測しましょう。

以下のように編集して実行します。


Sub sample_2()
 Debug.Print (110 / 1.1) = 100
 Debug.Print (110 / 1.1) < 100
End Sub

今度は、
  False
  True
と出力されます。

「100/1.1」は「100」ではなく「100」より小さいということがわかります。

更に以下のように編集して実行しましょう。


Sub sample_2()
 Debug.Print (110 / 1.1) = 100
 Debug.Print (110 / 1.1) < 100
 Debug.Print (110 / 1.1) > 99.9999
End Sub

今度は、
  False
  True
  True
と出力されます。

つまり「110/1.1」は「100」よりも小さく「99.9999」よりは大きいということです。

「100」よりも小さく「99.9999」より大きい数値を、Int関数の引数にsample_1 Subプロシージャの中では指定したので、「99.9999...」の小数部分を削った「99」が出力されたのです。

ちなみに「110/1.1」は、Pythonで「format(110/1.1, '.20f')」を実行すると「99.99999999999998578915」くらいの値であることを確認できます。

整数にしてから計算するサンプル

上記のような計算を正しく行う方法はいくつかあり、プログラミングに慣れた方なら型変換を行うのが一般的だと思いますが、整数にしてから計算する方法をまずは確認しましょう。


Sub sample_3()
 Debug.Print 110 * 10 / Int(1.1 * 10)
End Sub

以上のSubプロシージャなら期待どおり「100」が出力されます。

割る数を「1.1 * 10」と10倍して整数にするのにあわせて、割られる数も「110 * 10」と10倍しています。

最終更新日時:2020-02-07 04:54

[スポンサードリンク]

Home » いちばんやさしいExcel VBAの教本 » VBAで小数の計算が合わない?

TrackBack:0

TrackBack URL

Home » いちばんやさしいExcel VBAの教本 » VBAで小数の計算が合わない?

「いちばんやさしいExcel VBAの教本」の記事一覧

検索


Copyright © インストラクターのネタ帳 All Rights Reserved.

.