Странное поведение Labwindows при добавлении ДВОЙНЫХ номеров

Я запускаю следующий блок кода внутри функции CALLBACK для таймера.

if (start_value <= end_value) 
{
   start_value += increment_value;
}
else
{
   return 0;
}

все три переменные определены как DOUBLE.

Double start_value = 26.0;
Double end_value = 28.0;
increment_value = 0.1;

при добавлении increment_value к start_value значение переменной start_value не просто отражает ожидаемый результат добавления. Например, когда start_value равно 26.0, после одного добавления значение start_value равно 26.10000000001. Конечный 1 вызывает проблемы позже в коде, потому что, когда ожидаемый результат сравнения, как ожидается, будет ИСТИНА, он оценивается как ложный из-за конечного 1. Почему это происходит?

1 ответ

Решение

Эшан, The == Оператор ищет точное совпадение и должен использоваться исключительно для целочисленных сравнений (где возможно точное). Итак, "почему это происходит?" потому что 26.10000000001 не равно 26.1. Разница между ними иногда называется ошибкой с плавающей запятой.

Пока мы используем двоичное хранилище с плавающей запятой, ошибка с плавающей запятой будет продолжаться. Это требует, чтобы методы сравнения чисел с плавающей запятой отличались от методов сравнения целых чисел. (то есть для поплавков, не может использовать (x == y) ?, Быстрая и грязная альтернатива "==" при сравнении чисел с плавающей точкой - сделать что-то вроде этого: if(abs(x-y)<epsilon ){//equal} где эпсилон - небольшое значение допуска, например 0,000001

Итак, попробуйте что-то вроде этого:

int main(void)
{
    double start_value = 26.0;
    double end_value = 28.0;
    double increment_value = 0.1;

    #define EPSILON 0.000001  

    while(fabs(start_value-end_value)>EPSILON )
    {
          printf("not equal\n");
          start_value += increment_value;
    }
    printf("equal\n");
    getchar();  
}

Примечание: выберите значение epsilon, чтобы оно соответствовало окрестности значащих цифр в ваших сравнениях.

Есть много других хороших методов (и многие, кто скажет, что это не один из них), но я использовал этот в течение многих лет, и для моих целей он работал хорошо.
ЗДЕСЬ есть ссылка, немного рассказывающая об этом и других методах.

Другие вопросы по тегам