Сравнивать два двойника на равенство не удается - PullRequest
0 голосов
/ 12 ноября 2018

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

У меня есть оператор if:

    Dim TBC as Double: TBC = 0.10625
    Dim temp_g As Double: temp_g = Vol * USVol
    If TBC = temp_g Then
        ContinueCalculation = False
    ElseIf TBC > temp_g Then
        Stop 'you have an error.
    End If

Vol и USVol - это глобально определенные варианты.Vol = 0.125.USVol = 0.85.

0.85 * 0.125 = 0.10625

Я ожидаю, что оператор TBC = temp_g if сработает, и оператор ContinueCalculation = False ударится.Вместо этого код попадает в условие TBC > temp_g и код останавливается.

Есть идеи, почему это может происходить?

1 Ответ

0 голосов
/ 13 ноября 2018

Проблема

Проблема здесь носит технический математический характер.Компьютеры на самом деле не могут выполнять алгебраические вычисления, вместо этого они выполняют числовые вычисления с определенной точностью.Это означает, что математически результат может быть неверным, но довольно близким к правильному.

Поэтому нельзя сравнивать значения с плавающей запятой на равенство.

Значения в компьютерах не являются точными на 100%.Они точны только до определенного количества цифр.Например:

Number       Value
0.1          0.1 (of course)
float(.1)    0.100000001490116119384765625
double(.1)   0.1000000000000000055511151231257827021181583404541015625 

Чтение Сравнение чисел с плавающей запятой или Арифметика с плавающей запятой может дать неточные результаты в Excel для получения дополнительной справочной информации и способов ее правильной обработки..


Решение 1

Таким образом, вместо проверки на равенство If TBC = temp_g Then проверьте, меньше ли их различие, чем "небольшое число" 10⁻ⁿ, которое соответствует критериям точности, которые вы задаете длясчитайте эти два равными.

Например, вы можете использовать следующее (где n - количество цифр, необходимое для точности, чтобы считать их равными):

If (TBC - temp_g) ^ 2 < (10 ^ -n) ^ 2 Then

Обратите внимание, что мы должны заключить обе стороны в квадрат, чтобы убедиться в отсутствии отрицательных результатов.


Решение 2

В качестве альтернативы вы можете округлить оба значения до определенного количества цифр.для проверки на равенство.

If Round(TBC, 5) = Round(temp_g, 5) Then

Это будет считать TBC равным temp_g, если их первые 5 цифр совпадают.

...