VBAで十進数(Decimal)型を扱うときに使用する、CDec関数を解説します。
概要
小数を扱うメインの型である「Double型」と「Currency型」は、
- 割り算などの計算精度が高いのはDouble型
- 0.1などのキリの良い小数で誤差を出さないのがCurrency型
という特長があります。
この2つに今回紹介する「Decimal型」を加えた実行結果が以下の通りです。
' Double型はキリの良い小数に弱い Debug.Print CDbl(0.1) + CDbl(0.2) = 0.3 ' False ' Currency型はキリの良い小数に強い Debug.Print CCur(0.1) + CCur(0.2) = 0.3 ' True ' ただしCurrency型は小数点第4位しか扱えない Debug.Print CCur(0.00001) + CCur(0.00002) ' = 0 ' Decimal型なら高精度の小数を固定小数点として計算可 Debug.Print CDec(0.00001) + CDec(0.00002) ' = 0.00003
Decimal型は「固定小数点型の小数をどこに置くか設定できる」ような型で、
十進数型と呼ばれる通り、十進数を丸め誤差なく保持できます。
型としてはCurrency(通貨型 固定小数点型)の上位型にあたり、
主に小数点第5桁より小さい小数を精度よく計算する際に使用します。
ただし注意点として、VBAのDecimal型はあくまでCurrency型の上位版であり、
Double型の上位互換ではないという点は知っておいてください。
例えば以下のコードを見てわかるように、
Debug.Print CDbl(1 / 3) * 3 = 1 ' True Debug.Print CDec(1 / 3) * 3 = 1 ' False
1/3 × 3 という計算を0.999999999999999≠1と判定するため、
このくらい簡単な小数計算でもDouble型より低精度になることがあります。
結局割り算や数学関数を使うと浮動小数点には劣るということですね。
結局小数はどの型も一長一短がありますので、
やはり状況に応じて使い分ける他ないということになります。
使い方
Decimal型の特殊な仕様として、Decimal型の変数は宣言できません。
Dim x As Decimal ' ← コンパイルエラー
Decimal型を使用する場合は、一旦Variant型変数を用意し、
値の代入時にCDec関数をかませて代入します。
Dim x As Varinat x = CDec(格納したい値)
以降の計算は「より精度が高い方に合わせて」計算されますので、
Debug.Print Typename(CDec(0.1)+CDbl(0.1)) ' = Decimal
このようにひとつDecimal型があれば計算はDecimal型として行われます。
使用するすべての数値をDecimal型として宣言する必要はありません。
前述の通り、キリの良い小数の+-×は高精度でこなしますが、
割り切れない小数の精度がDouble型より高いわけではありません。
基本はDouble型とCurrency型を使い分け、
Decimal型はどうしてもというときにだけ使用するといいと思います。