Некорректная работа с действительными числами (числами с плавающей точкой).

 

Столкнулся с такой проблемой. Представляю уже переписанный код для простоты и наглядности.

extern double x=0.0;
extern double y=0.0;
extern double z=0.0;
double r;
double start()
{
   r=x-y;
   Alert (z,", ",r);
   if (z==r)
   {
      Alert ("z равно x-y.");
   }
   else
   {
      if (z<r)
      {
         Alert ("z меньше x-y.");
      }
      else
      {
         Alert ("z больше x-y.");
      }
   }
   return;
}

// 1 inputs: x=2.2; y=1.1; z=1.1; 
// 2 inputs: x=1.2; y=1.1; z=0.1;
// 3 inputs: x=1.02; y=1.01; z=0.01; 

Опишу как по моему должно все работать.

При тестировании советника вводим данные из первой, из второй или из третьей строки коментариев и начинаем тестировать.

Теперь собственно код.

Вычисляем x-y и присваиваем найденное значение переменной r.

Для наглядности выводим значения переменных z и r.

Проверяем равность z и r. Если равны - выводим сообщение. Иначе они не равны (одно из них больше другого) - переходим дальше.

Уточняем значение какой переменной меньше. Если z меньше r - выводим сообщение, иначе z больше r - переходим дальше и выводим сообщение.

Теперь о проблеме. Если размышлять логически - ввод данных любой из трех строк коментария должен вывести сообщение "z равно x-y.", так почему же у всех строчек разный результат, и правильный только у первой строчки.

Мне кажется, код написан правильно, так что грешу на криворукость разработчиков. Если не прав - прошу объяснить мою ошибку и вообще жду мыслей.

 

Нормализовать до нужного количества знаков после запятой: "r = NormalizeDouble(x-y,2);"

r = 2.200000001-1.1000000002 = 1.1000000008 и не равно z=1.1

 
djon1son:

Столкнулся с такой проблемой. Представляю уже переписанный код для простоты и наглядности.

Опишу как по моему должно все работать.

При тестировании советника вводим данные из первой, из второй или из третьей строки коментариев и начинаем тестировать.

Теперь собственно код.

Вычисляем x-y и присваиваем найденное значение переменной r.

Для наглядности выводим значения переменных z и r.

Проверяем равность z и r. Если равны - выводим сообщение. Иначе они не равны (одно из них больше другого) - переходим дальше.

Уточняем значение какой переменной меньше. Если z меньше r - выводим сообщение, иначе z больше r - переходим дальше и выводим сообщение.

Теперь о проблеме. Если размышлять логически - ввод данных любой из трех строк коментария должен вывести сообщение "z равно x-y.", так почему же у всех строчек разный результат, и правильный только у первой строчки.

Мне кажется, код написан правильно, так что грешу на криворукость разработчиков. Если не прав - прошу объяснить мою ошибку и вообще жду мыслей.


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

 
evillive:

Нормализовать до нужного количества знаков после запятой: "r = NormalizeDouble(x-y,2);"

r = 2.200000001-1.1000000002 = 1.1000000008 и не равно z=1.1



Ну да. Есть такая "штука", как эпсилон. Числа, различающиеся на эпсилон, равны. Хотя, физически не равны. Не обязательно вычислять с такой высокой точностью, как до эпсилон. Можно точность понизить.
 

Спасибо evillive.

VladislavVG - извини, я не понял из названия "Почему 0.0039 > 0.0039 и 0.0039 >= 0.0039 одинаковы" что это мой случай. Каюсь. Виновен.

 
djon1son:

Спасибо evillive.

VladislavVG - извини, я не понял из названия "Почему 0.0039 > 0.0039 и 0.0039 >= 0.0039 одинаковы" что это мой случай. Каюсь. Виновен.


Та мне-то что ? Это Вам в первую очередь надо. Таких вопросов, которые у Вас еще возникнут, а на форуме уже рассмотрены - вагон.
 
В любом случае спасибо, и постараюсь более умело пользоваться поиском, я сам говорю "нужно искать, ведь ктото уже с этим столкнулся".
Причина обращения: