Сравнение чисел double - ошибка !? - страница 2

 

У человека проблема не в округлении.

Сравнение 23506.0 и 23568.0  всегда даст правильный результат. Но он не хочет более полный код выкладывать, чтобы проверить можно было.

 
vlad-mir:

double ray =  ObjectGetValueByTime(0, ray_name, mrate_M5[i].time, 0);
     

и вот что выдает

2018.08.18 20:40:12.791 2018.07.11 21:45:00   !!!!!  mrate_M5[i].high > ray   !!!!!!   ray_= 23568.0,  цена high=23506.0,  время =2018.07.10 16:25:00

// однако цена меньше ray , через раз выдает то правильно , то неправильно

Это ошибка терминала?

Сообщите пожалуйста, Вы используете новые MQL5 функции iHigh, iLow и т.д. ?

Если да, сообщите пожалуйста билд терминала.

В реализации данных функций была исправлена ошибка, которая могла привести к подобной ошибке сравнения.

 
Ilyas:

Сообщите пожалуйста, Вы используете новые MQL5 функции iHigh, iLow и т.д. ?

Если да, сообщите пожалуйста билд терминала.

В реализации данных функций была исправлена ошибка, которая могла привести к подобной ошибке сравнения.

1) терминал 5 версия, 1881

2)  функции  iHigh, iLow не использую

3) NormalizeDouble не помогает ни при каких вариантах

 
vlad-mir:
1) терминал 5 версия, 1881

2)  функции  iHigh, iLow не использую

3) NormalizeDouble не помогает ни при каких вариантах

Без бОльшего кода Вам вряд ли помогут. Пусть не весь, но хотя бы часть, чтобы было можно воспроизвести ошибку.

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

double    _ray = mrate_M5[i].high;
...
double ray =  ObjectGetValueByTime(0, ray_name, _time, 0);

Эти две строки возвращают разные значения, 23568 и 23506. Они не равны, даже если их сравнивать не как double, а как целые. Почему они должны быть равными, а оказались различными - этот вопрос и поставлен. Дело совсем не в том, как сравнивать double.

Как автор написал остальное, неизвестно. Также, как то, почему значения _ray и ray должны, по его мнению, совпадать в момент вызова ObjectGetValueByTime. Эти строки идут вовсе не подряд, а что происходит между ними, он не сообщает.

 
Vladimir:

Как автор написал остальное, неизвестно. Также, как то, почему значения _ray и ray должны, по его мнению, совпадать в момент вызова ObjectGetValueByTime. Эти строки идут вовсе не подряд, а что происходит между ними, он не сообщает.

Штирлиц никогда не был так близок к провалу. )))

 

Спасибо кто посоветовал преобразовать число в int - помогло только это. NormalizeDouble не помогает ни при каких вариантах

      double ray_1_3_ =  NormalizeDouble(ObjectGetValueByTime(0, ray_1_3_name, mrate[i].time, 0),Digits()); 
    
      int ray_1_3_int = (int)(ray_1_3_ *10000);                // Защита от глюка (не может сравнивать double)
      int mrate_high_int = (int)(mrate[i].high *10000);
      
      if(ray_1_3_int < mrate_high_int  
      ){
    … все работает

 
      }
 
vlad-mir:

Спасибо кто посоветовал преобразовать число в int - помогло только это. NormalizeDouble не помогает ни при каких вариантах

Оно и не может помочь - сравнение идет не в напечатанном тексте на экране, а в регистрах процессора. А там есть свои особенности.
 
Mikhail Mitin:

Числа Double - числа с плавающий запятой, пример как это работает:

  • вы пишите double a = 1.222, b = 1.222; и думаете, что они равны,
  • но на самом деле, там может быть: a = 1.21999999999   и    b = 1.222000001   и значение a==b не будет Истиной
  • при этом вы можете написать следующий строкой: double c = a   и    при следующей проверке (a==c) это тоже может не быть истиной


Я сравниваю double так:

  1. я нормализую оба числа: NormalizeDouble(a, _Digits)
  2. сравниваю их разность


Как-то один опытный программист (с опытом 20+ лет) сказал мне, что в безотказных крупных системах (конкретно он пишет софт для нефтезаводов) уходят от типа double в пользу int, потому что с int такой ситуации невозможно

Спасибо!

Причина обращения: