Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Добавляй наш канал в Twitter'e и следи за новостями!
Forex Trader
114252
Forex Trader 2005.11.21 18:32 
Код эксперта для проверки, с пояснениями, и собственно сам вопрос (последний билд)
bool t = true;
int start()
  {
double X1 = 0.780; // фанарные числа
double Y1 = 0.684;
double X2 = 0.684;
double Y2 = 0.780;

double H = 20.0;

if (t) 
    {
     double N1,N2;
     N1 = (X1 - Y1)/(H * Point);
     N2 = (X2 - Y2)/(H * Point);

     Print("функция Print() по-разному печатает в журнал double переменные через разделитель (,) и (+)");
     Print("исходное число N1 (вычисленно из других чисел) = ", N1, " разделитель (,)"); 
     Print("исходное число N2 (вычисленно из других чисел) = " + N2 + " разделитель(+)"); 

     double P1 = 48.0;
     double P2 = -48.0;
     Print("исходное число P1 (начальное) = ", P1); 
     Print("исходное число P2 (начальное) = ", P2); 
     
     Print("--------------");

     Print("ошибка сравнения double переменных if (N1 != P1) и if (N2 != P2)");
     if (N1 != P1)
         {
          Print(N1, " != ", P1);
          }
     if (N2 != P2)
         {
          Print(N2, " != ", P2);
          }
          
          Print("--------------");
          
          Print("ошибка функции MathFloor(), применительно к числу N");
          Print("число N1 = ", N1, ", число N1 после MathCeil = ", MathCeil(N1));
          Print("число N1 = ", N1, ", число N1 после MathFloor = ", MathFloor(N1));

          Print("число P1 = ", P1, ", число P1 после MathCeil = ", MathCeil(P1));
          Print("число P1 = ", P1, ", число P1 после MathFloor = ", MathFloor(P1));
          
          Print("--------------");
          
          Print("ошибка функции MathCeil(), применительно к числу N");
          Print("число N2 = ", N2, ", число N2 после MathCeil = ", MathCeil(N2));
          Print("число N2 = ", N2, ", число N2 после MathFloor = ", MathFloor(N2));

          Print("число P2 = ", P2, ", число P2 после MathCeil = ", MathCeil(P2));
          Print("число P2 = ", P2, ", число P2 после MathFloor = ", MathFloor(P2));
     
     t= false;
     }
   return(0);
  }


вот результат, где и так все видно.
???????????????????????????????????

18:27:43 XXX AUDUSD,M1: loaded successfully
18:27:44 XXX started for testing
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: функция Print() по-разному печатает в журнал double переменные через разделитель (,) и (+)
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: исходное число N1 (вычисленно из других чисел) = 48 разделитель (,)
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: исходное число N2 (вычисленно из других чисел) = -48.00000000 разделитель(+)
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: исходное число P1 (начальное) = 48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: исходное число P2 (начальное) = -48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: --------------
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: ошибка сравнения double переменных if (N1 != P1) и if (N2 != P2)
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: 48 != 48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: -48 != -48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: --------------
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: ошибка функции MathFloor(), применительно к числу N
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: число N1 = 48, число N1 после MathCeil = 48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: число N1 = 48, число N1 после MathFloor = 47
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: число P1 = 48, число P1 после MathCeil = 48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: число P1 = 48, число P1 после MathFloor = 48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: --------------
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: ошибка функции MathCeil(), применительно к числу N
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: число N2 = -48, число N2 после MathCeil = -47
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: число N2 = -48, число N2 после MathFloor = -48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: число P2 = -48, число P2 после MathCeil = -48
18:27:44 2004.06.15 23:42  XXX AUDUSD,M1: число P2 = -48, число P2 после MathFloor = -48
MetaQuotes Software Corp.
Модератор
180171
MetaQuotes Software Corp. 2005.11.21 21:53  
Спасибо за проведенные исследования.
К счастью, результаты MQL4 расчетов 100% верны.

Перенесем код в C/C++ компилятор (взят Visual C++ 6.0):
int main()
  {
   double X1=0.780; // фанарные числа
   double Y1=0.684;
   double X2=0.684;
   double Y2=0.780;

   double H=20.0;
   double Point=0.0001;
   double N1,N2;
//----
   N1=(X1-Y1)/(H * Point);
   N2=(X2-Y2)/(H * Point);

     double P1=48.0;
     double P2=-48.0;
     printf("исходное число P1 (начальное) = %lf\n", P1);
     printf("исходное число P2 (начальное) = %lf\n", P2);

     printf("--------------\n");

     printf("ошибка сравнения double переменных if (N1 != P1) и if (N2 != P2)\n");
     if(N1!=P1) printf("%lf != %lf\n",N1,P1);
     if(N2!=P2) printf("%lf != %lf\n", N2, P2);

     printf("--------------\n");

     printf("ошибка функции MathFloor(), применительно к числу N\n");
     printf("число N1 = %lf , число N1 после MathCeil = %lf\n",N1, ceil(N1));
     printf("число N1 = %lf , число N1 после MathFloor = %lf\n",N1, floor(N1));

     printf("число P1 = %lf , число P1 после MathCeil = %lf\n", P1,ceil(P1));
     printf("число P1 = %lf , число P1 после MathFloor = %lf\n",P1,floor(P1));

     printf("--------------\n");

     printf("ошибка функции MathCeil(), применительно к числу N\n");
     printf("число N2 = %lf , число N2 после MathCeil = %lf\n", N2,ceil(N2));
     printf("число N2 = %lf , число N2 после MathFloor = %lf\n", N2,floor(N2));

     printf("число P2 = %lf , число P2 после MathCeil = %lf\n", P2,ceil(P2));
     printf("число P2 = %lf , число P2 после MathFloor = %lf\n",P2,floor(P2));
//----
   return(0);
  }



Запустим и получим точно такой же результат, что и в MQL4:

исходное число P1 (начальное) = 48.000000
исходное число P2 (начальное) = -48.000000
--------------
ошибка сравнения double переменных if (N1 != P1) и if (N2 != P2)
48.000000 != 48.000000
-48.000000 != -48.000000
--------------
ошибка функции MathFloor(), применительно к числу N
число N1 = 48.000000 , число N1 после MathCeil = 48.000000
число N1 = 48.000000 , число N1 после MathFloor = 47.000000
число P1 = 48.000000 , число P1 после MathCeil = 48.000000
число P1 = 48.000000 , число P1 после MathFloor = 48.000000
--------------
ошибка функции MathCeil(), применительно к числу N
число N2 = -48.000000 , число N2 после MathCeil = -47.000000
число N2 = -48.000000 , число N2 после MathFloor = -48.000000
число P2 = -48.000000 , число P2 после MathCeil = -48.000000
число P2 = -48.000000 , число P2 после MathFloor = -48.000000



Такие вопросы периодически возникают в форуме и связаны они с тем, что операции сравнения с вещественными числами имеют ряд особенностей из-за потери точности. То, что числа до 5-6 разряда выглядят одинаково, не значит, что они на самом деле одинаковы.

На всякий случай повторю: ошибок тут нет вообще.

Forex Trader
114252
Forex Trader 2005.11.22 01:21  
То, что числа до 5-6 разряда выглядят одинаково, не значит, что они на самом деле одинаковы.

Правильно ли полагать, что нормализация до 4 знака полностью решает эту проблему?
MetaQuotes Software Corp.
Модератор
180171
MetaQuotes Software Corp. 2005.11.22 10:24  
То, что числа до 5-6 разряда выглядят одинаково, не значит, что они на самом деле одинаковы.

Правильно ли полагать, что нормализация до 4 знака полностью решает эту проблему?

Нормализация перед сравнением должна решать проблему сравнения.
Главное, не использовать "сырое" сравнение вещественных чисел.
Forex Trader
114252
Forex Trader 2005.11.22 11:36  

Нормализация перед сравнением должна решать проблему сравнения.
Главное, не использовать "сырое" сравнение вещественных чисел.

Действительно ТАК!!!
Предложение, раз уж сравнивать приходиться очень часто и почти всегда, написать в хелпе большими буквами что-то вроде текста выше, а еще лучше где-нибудь на рамке эдитора, при попытке юзера что-либо сравнить (<>=) появляестя та самая надпись, и начинает мигать как сумасшедшая, менять цвета, нагнетать страх и ужас, производить зловещие звуки, тренд превращается в голодного змея и набрасывается на мышку ЫЫЫЫЫЫЫ, чуть руку не отгрыз :) оу, чего это я, ночные кошмары замучали......

Спасибо за объяснение. С уважением.
Forex Trader
114252
Forex Trader 2005.11.22 11:54  
Renat,
ОК, спасибо.
/
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий