Excel VBAで2つのdoubleを比較するのに問題があります
次のコードがあるとします
Dim a as double
Dim b as double
a = 0.15
b = 0.01
b を少し操作した後、b は 0.6 になりました。
ただし、 double データ型に関連する不正確さは頭痛の種です。
if a = b then
//this will never trigger
end if
double 型の末尾の不正確さを取り除く方法を知っていますか?
Excel VBAで2つのdoubleを比較するのに問題があります
次のコードがあるとします
Dim a as double
Dim b as double
a = 0.15
b = 0.01
b を少し操作した後、b は 0.6 になりました。
ただし、 double データ型に関連する不正確さは頭痛の種です。
if a = b then
//this will never trigger
end if
double 型の末尾の不正確さを取り除く方法を知っていますか?
浮動小数点値が等しいかどうかを比較することはできません。固有エラーの処理方法については、この記事「浮動小数点数の比較」を参照してください。
浮動小数点数の絶対範囲が事前にわかっていない限り、一定の誤差範囲と比較するほど単純ではありません。
if you are going to do this....
Dim a as double
Dim b as double
a = 0.15
b = 0.01
you need to add the round function in your IF statement like this...
If Round(a,2) = Round(b,2) Then
//code inside block will now trigger.
End If
See also here for additional Microsoft reference.
double が等しいかどうかを比較することは決して賢明ではありません。
一部の 10 進数値は、複数の浮動小数点表現にマップされます。したがって、一方の 0.6 が常に他方の 0.6 と等しいとは限りません。
一方を他方から引くと、おそらく 0.00000000051 のようになります。
これで、差が特定の誤差範囲よりも小さいことを等価と定義できるようになりました。
ここに私が書いた簡単な関数があります:
Function dblCheckTheSame(number1 As Double, number2 As Double, Optional Digits As Integer = 12) As Boolean
If (number1 - number2) ^ 2 < (10 ^ -Digits) ^ 2 Then
dblCheckTheSame = True
Else
dblCheckTheSame = False
End If
End Function
次のように呼び出します。
MsgBox dblCheckTheSame(1.2345, 1.23456789)
MsgBox dblCheckTheSame(1.2345, 1.23456789, 4)
MsgBox dblCheckTheSame(1.2345678900001, 1.2345678900002)
MsgBox dblCheckTheSame(1.2345678900001, 1.2345678900002, 14)
指摘されているように、多くの 10 進数は従来の浮動小数点型として正確に表すことができません。問題空間の性質によっては、特定の小数点までの完全な精度で 10 進数 (基数 10) を表すことができる Decimal VBA タイプを使用する方がよい場合があります。これは、たとえば 2 桁の 10 進数の精度が必要な場合など、お金を表すためによく行われます。
Dim a as Decimal
Dim b as Decimal
a = 0.15
b = 0.01
通貨データ型は、適切な代替手段となる場合があります。4 桁の固定精度で比較的大きな数を処理します。