VBA 정밀 문제의 이중을 비교하십시오
-
04-07-2019 - |
문제
Excel VBA에서 2 더블을 비교하는 데 어려움이 있습니다
다음 코드가 있다고 가정합니다
Dim a as double
Dim b as double
a = 0.15
b = 0.01
B에 대해 몇 번의 조작 후 B는 이제 0.6입니다.
그러나 이중 데이터 유형과 관련된 부정확성은 두통을줍니다.
if a = b then
//this will never trigger
end if
내가 이중 유형에서 후행 부정확성을 제거 할 수있는 방법을 알고 있습니까?
해결책
평등에 대한 부동 소수점 값을 비교할 수 없습니다. 이 기사를 참조하십시오 "부동 소수점 수치 비교"고유 오류를 처리하는 방법에 대한 논의.
플로트의 절대 범위가 사전에 무엇인지 확실하지 않은 한 일정한 오류 마진과 비교하는 것만 큼 간단하지 않습니다.
다른 팁
당신이 이것을하려고한다면 ....
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 참조는 다음과 같습니다.
평등에 대한 복식을 비교하는 것은 결코 현명하지 않습니다.
일부 소수점 값은 여러 부동 소수점 표현에 매핑됩니다. 따라서 하나의 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 진수 VBA 유형을 사용하는 것이 좋습니다. 이것은 예를 들어 2 자리 소수판 정밀도가 종종 원하는 경우에 돈을 나타내는 경우가 종종 있습니다.
Dim a as Decimal
Dim b as Decimal
a = 0.15
b = 0.01
통화 데이터 유형은 좋은 대안 일 수 있습니다. 고정 된 4 자리 정밀도로 비교적 많은 수를 처리합니다.
일이 길다 ?? 이것이 모든 시나리오에 답변할지 확실하지 않지만 VBA의 둥근 이중 값을 비교하는 문제가 발생했습니다. 반올림 후 동일한 숫자와 비교할 때 VBA는 if-then 비교 문에서 False를 트리거합니다. 내 수정 사항은 먼저 두 배로 문자열에서 문자열을 한 다음 문자열에서 두 배가 된 다음 비교를 수행하는 것이 었습니다.
시뮬레이션 된 예이 게시물에 언급 된 오류를 일으킨 정확한 숫자를 기록하지 않았으며 예제의 금액은 현재 문제를 트리거하지 않으며 문제 유형을 나타내려고합니다.
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