Сравните двойную точность в задаче точности VBA
У меня есть проблема сравнения двух двойных в 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
Знаете ли вы, как я могу удалить конечную неточность в двойном типе?
Ответы
Ответ 1
Вы не можете сравнивать значения с плавающей запятой для равенства. См. Эту статью в разделе " Сравнение чисел с плавающей запятой" для обсуждения того, как обрабатывать внутреннюю ошибку.
Это не так просто, как сравнение с постоянным пределом ошибки, если вы точно не знаете, что такое абсолютный диапазон поплавков.
Ответ 2
если вы собираетесь сделать это....
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.
Ответ 3
Никогда не бывает разумно сравнивать двойники на равенстве.
Некоторые десятичные значения относятся к нескольким представлениям с плавающей запятой. Таким образом, один 0,6 не всегда равен другому 0,6.
Если мы вычтем один из другого, мы, вероятно, получим что-то вроде 0,00000000051.
Теперь мы можем определить равенство как меньшую разницу, чем определенный запас ошибки.
Ответ 4
Вот простая функция, которую я написал:
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)
Ответ 5
Как уже отмечалось, многие десятичные числа не могут быть представлены точно как традиционные типы с плавающей запятой. В зависимости от характера вашего проблемного пространства вам может быть лучше использовать десятичный тип VBA, который может представлять десятичные числа (база 10) с совершенной точностью до определенной десятичной точки. Это часто делается для представления денег, например, где часто требуется двузначная десятичная точность.
Dim a as Decimal
Dim b as Decimal
a = 0.15
b = 0.01
Ответ 6
Тип данных валюты может быть хорошей альтернативой. Он обрабатывает относительно большие числа с фиксированной точностью в четыре цифры.
Ответ 7
Работа круглой?? Не уверен, что это будет отвечать всем сценариям, но я столкнулся с проблемой сравнения округленных двойных значений в 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, " & 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