質問

Excel VBAで2つのダブルを比較するのに問題があります

次のコードがあるとします

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型の末尾の不正確さを削除する方法を知っていますか?

役に立ちましたか?

解決

浮動小数点値が等しいかどうかを比較することはできません。 " 浮動小数点の比較に関する記事を参照してください。数字"固有エラーの処理方法については、

フロートの絶対範囲が事前にわかっている場合を除き、一定のエラーマージンと比較するほど簡単ではありません。

他のヒント

これを行う場合....

Dim a as double  
 Dim b as double  
 a = 0.15  
 b = 0.01

次のようにIFステートメントにラウンド関数を追加する必要があります...

  If Round(a,2) = Round(b,2) Then   
     //code inside block will now trigger.
  End If  

その他のMicrosoftリファレンスについてはこちらも参照してください。

平等でdoubleを比較することは賢明ではありません。

一部の小数値は、いくつかの浮動小数点表現にマップされます。したがって、1つの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桁の固定精度で比較的大きな数値を処理します。

回避策?? これがすべてのシナリオに答えるかどうかはわかりませんが、VBAの丸められたdouble値を比較する際に問題が発生しました。丸め後に同一であると思われる数値と比較すると、VBAはif-then比較ステートメントでfalseをトリガーします。 私の修正は、最初にdoubleからstring、次にstringからdoubleの2つの変換を実行してから、比較を実行することでした。

シミュレーション例 この投稿で言及されたエラーの原因となった正確な数字を記録しませんでした。私の例の金額は現在問題を引き起こしておらず、問題の種類を表すことを意図しています。

 Sub Test_Rounded_Numbers()

      Dim Num1 As Double

      Dim Num2 As Double

      Let Num1 = 123.123456789

      Let Num2 = 123.123467891

      Let Num1 = Round(Num1, 4) '123.1235


      Let Num2 = Round(Num2, 4) '123.1235

      If Num1 = Num2 Then

           MsgBox "Correct Match, " & Num1 & " does equal " & Num2
      Else
           MsgBox "Inccorrect Match, " & Num1 & " does not equal " & Num2
      End If

      'Here it would say that "Inccorrect Match, 123.1235 does not equal 123.1235."

 End Sub

 Sub Fixed_Double_Value_Type_Compare_Issue()

      Dim Num1 As Double

      Dim Num2 As Double

      Let Num1 = 123.123456789

      Let Num2 = 123.123467891

      Let Num1 = Round(Num1, 4) '123.1235


      Let Num2 = Round(Num2, 4) '123.1235

      'Add CDbl(CStr(Double_Value))
      'By doing this step the numbers
      'would trigger if they matched
      '100% of the time

      If CDbl(CStr(Num1)) = CDbl(CStr(Num2)) Then

           MsgBox "Correct Match"
      Else
           MsgBox "Inccorrect Match"

      End If

      'Now it says Here it would say that "Correct Match, 123.1235 does equal 123.1235."
 End Sub
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top