Так что я просто углублюсь в эту проблему ... У меня есть интенсивно используемое веб-приложение, которое впервые за 2 года не смогло выполнить проверку на равенство двух двойных чисел с помощью функции равенства коллегасказал, что он также использовал в течение многих лет.
Цель функции, которую я собираюсь вставить, состоит в том, чтобы сравнить два двойных значения с 4 цифрами точности и вернуть результаты сравнения.Для иллюстрации мои значения:
Dim double1 As Double = 0.14625000000000002 ' The result of a calculation
Dim double2 As Double = 0.14625 ' A value that was looked up in a DB
Если я передам их в эту функцию:
Public Shared Function AreEqual(ByVal double1 As Double, ByVal double2 As Double) As Boolean
Return (CType(double1 * 10000, Long) = CType(double2 * 10000, Long))
End Function
сравнение не удастся.После умножения и приведения к Long, сравнение заканчивается следующим образом:
Return 1463 = 1462
Я вроде отвечаю на свой вопрос здесь, но я вижу, что double1
находится в пределах точности двойного (17 цифр) и актерский состав работает правильно.
Мой первый настоящий вопрос: если я поменяю строку выше на следующую, почему она работает правильно (возвращает True
)?
Return (CType(CType(double1, Decimal) * 10000, Long) = _
CType(CType(double2, Decimal) * 10000, Long))
Не Decimal
еще больше точности, поэтому приведение к Long должно быть равно 1463
, а возвращаемое сравнение False
?Я думаю, у меня есть мозги пердеть на этом материале ...
Во-вторых, если бы кто-то изменил эту функцию, чтобы сделать сравнение я ищу более точным или менее подверженным ошибкам, вы бы порекомендовали изменитьэто к чему-то намного проще?Например:
Return (Math.Abs(double1 - double2) < 0.0001)
Буду ли я сумасшедшим, чтобы попробовать что-то вроде:
Return (double1.ToString("N5").Equals(double2.ToString("N5")))
(Я бы никогда не сделал выше, мне просто любопытно, как вы реагируете. Это было быужасно неэффективно в моем приложении.)
В любом случае, если бы кто-то мог пролить свет на разницу, которую я вижу между приведением Double
с и Decimal
с к Long
, это было бы здорово.
Спасибо!