Sammenligne dobbelt i VBA presisjon problem

stemmer
9

Jeg har problemer med å sammenligne to doble i Excel VBA

anta at jeg har følgende kode

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

Etter noen manipulasjoner på b, er nå lik 0,6 b

men unøyaktighet knyttet til dobbel datatype gir meg hodepine fordi

if a = b then
 //this will never trigger
end if

Vet du hvordan jeg kan fjerne slepe unøyaktighet på dobbel type?

Publisert på 24/10/2008 klokken 20:05
kilden bruker
På andre språk...                            


7 svar

stemmer
3

Det er aldri lurt å sammenligne dobles på likeverd.

Noen desimalverdier kart til flere flyttall representasjoner. Så en 0.6 er ikke alltid lik den andre 0,6.

Hvis vi trekker fra hverandre, vi sannsynligvis få noe som ,00000000051.

Vi kan nå definere likestilling som å ha en forskjell mindre at en viss feilmargin.

Svarte 24/10/2008 kl. 20:09
kilden bruker

stemmer
14

Du kan ikke sammenligne flyttall verdier for likestilling. Se denne artikkelen på " Sammenligning av flyttall " for en diskusjon om hvordan man skal håndtere den iboende feil.

Det er ikke så enkelt som å sammenligne med en konstant feilmargin med mindre du vet sikkert hva den absolutte spekter av flottørene er på forhånd.

Svarte 24/10/2008 kl. 20:12
kilden bruker

stemmer
2

Som det har blitt påpekt, kan mange desimaltall ikke gjengis presist som tradisjonelle flyttyper. Avhengig av natur problemet plass, kan du bli bedre av med desimal VBA type som kan representere desimaltall (base 10) med perfekt presisjon opp til en viss desimaltegn. Dette er ofte gjort for å representere penger for eksempel der to-sifret desimal presisjon er ofte ønskelig.

Dim a as Decimal
Dim b as Decimal
a = 0.15
b = 0.01
Svarte 24/10/2008 kl. 21:18
kilden bruker

stemmer
1

Valutadatatype kan være et godt alternativ. Den håndterer relativt store mengder med fast firesifret presisjon.

Svarte 27/10/2008 kl. 19:36
kilden bruker

stemmer
5

Hvis du skal gjøre dette ....

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

du må legge runden funksjonen i IF-setning som dette ...

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

Se også her for ytterligere Microsoft referanse .

Svarte 07/04/2011 kl. 04:14
kilden bruker

stemmer
4

Her er en enkel funksjon jeg skrev:

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

Kall det med:

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)
Svarte 04/06/2014 kl. 13:14
kilden bruker

stemmer
0

Arbeid-en-rund ?? Ikke sikker på om dette vil svare på alle scenarioer, men jeg kjørte på et problem å sammenligne avrundede doble verdiene i VBA. Når jeg sammenlignet med tall som syntes å være identisk etter avrunding, ville VBA utløse falsk i en if-then sammenligne uttalelse. Min løsning var å kjøre to konverteringer, første dobbel til streng, så streng å doble, og gjør deretter sammenligne.

Simulert Eksempel jeg ikke ta de eksakte tallene som forårsaket feilen er nevnt i dette innlegget, og beløpene i mitt eksempel ikke utløser problemet for øyeblikket, og er ment å representere den type spørsmål.

 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
Svarte 06/06/2019 kl. 19:53
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more