Сравните двойной в точности задачи VBA

excel vba comparison double

30774 просмотра

7 ответа

У меня проблемы при сравнении 2-х двойных в Excel VBA

Предположим, что у меня есть следующий код

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

Знаете ли вы, как я могу убрать конечную неточность в двойном типе?

Автор: Eric Источник Размещён: 06.06.2019 08:58

Ответы (7)


14 плюса

Решение

Вы не можете сравнить значения с плавающей запятой на равенство. См. Эту статью « Сравнение чисел с плавающей запятой » для обсуждения того, как обрабатывать внутреннюю ошибку.

Это не так просто, как сравнивать с постоянным запасом ошибок, если вы не знаете наверняка, что такое абсолютный диапазон значений с плавающей точкой.

Автор: Rob Walker Размещён: 24.10.2008 10:12

6 плюса

если вы собираетесь сделать это ....

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 .

Автор: Anonymous Type Размещён: 07.04.2011 06:14

5 плюса

Никогда не стоит сравнивать двойники на равенство.

Некоторые десятичные значения отображаются в несколько представлений с плавающей точкой. Так что один 0,6 не всегда равен другому 0,6.

Если мы вычтем одно из другого, мы, вероятно, получим что-то вроде 0,00000000051.

Теперь мы можем определить равенство как имеющее разницу меньше определенной границы ошибки.

Автор: Toon Krijthe Размещён: 24.10.2008 10:09

5 плюса

Вот простая функция, которую я написал:

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)
Автор: user3706920 Размещён: 04.06.2014 03:14

3 плюса

Как уже указывалось, многие десятичные числа не могут быть представлены точно как традиционные типы с плавающей точкой. В зависимости от природы вашего проблемного пространства, вам может быть лучше использовать тип Decimal VBA, который может представлять десятичные числа (основание 10) с идеальной точностью до определенной десятичной запятой. Это часто делается для представления денег, например, когда часто требуется двузначная десятичная точность.

Dim a as Decimal
Dim b as Decimal
a = 0.15
b = 0.01
Автор: C. Dragon 76 Размещён: 24.10.2008 11:18

1 плюс

Тип данных Currency может быть хорошей альтернативой. Он обрабатывает относительно большие числа с фиксированной точностью до четырех цифр.

Автор: DJ. Размещён: 27.10.2008 09:36

0 плюса

Работа круглой ?? Не уверен, что это будет отвечать всем сценариям, но я столкнулся с проблемой сравнения округленных двойных значений в VBA. Когда я сравнивал числа, которые после округления оказались идентичными, VBA вызывал ложь в операторе сравнения if-then. Мое исправление состояло в том, чтобы запустить два преобразования: сначала двойное в строку, затем двойное в строку, а затем выполнить сравнение.

Смоделированный пример Я не записал точные числа, которые привели к ошибке, упомянутой в этом посте, и суммы в моем примере не вызывают проблему в настоящее время и предназначены для представления типа проблемы.

 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"
      Else
           MsgBox "Inccorrect Match"
      End If

 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

 End Sub
Автор: Josh Anstead Размещён: 06.06.2019 05:53
Вопросы из категории :
32x32