2008-10-24 3 views
8

у меня есть проблема сравнения 2 двойника в Excel VBAСравните дважды в VBA прецизионных проблемах

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

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

После нескольких манипуляций на Ь, Ь теперь равен 0,6

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

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

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

ответ

13

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

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

+1

Для другой ссылки вы можете проверить http://msdn.microsoft.com/en-us/ библиотека/ae382yt8 (VS.80) .aspx – ZCHudson 2008-10-24 22:14:48

3

Никогда не бывает разумным сравнивать двойники на равенстве.

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

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

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

1

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

Dim a as Decimal 
Dim b as Decimal 
a = 0.15 
b = 0.01 
+0

Доступна ли десятичная запятая в vba? Я думаю, вам нужно объявить как вариант, а затем отбросить до десятичного с помощью Cdec (myVar). – 2008-10-25 16:26:47

1

Данные валюты могут быть хорошей альтернативой. Он обрабатывает относительно большие числа с фиксированной точностью в четыре цифры.

3

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

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 

Смотрите также here for additional Microsoft reference.

2

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

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)