Особенности языка mql5, тонкости и приёмы работы - страница 241

 
fxsaber #:

Вы отказываетесь понимать.

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

 
amrali #:

As long as the two amounts are equal, any one of them is a valid minimum. Consider MathMin(1, 1), it does not differ if the the function returns the first (1) or second (1).

So, returning 0.0 is not different from -0.0.

Edit: by the way, the two highlighted expressions are NOT identical.

Пожалуй соглашусь с коллегой amrali. Ещё добавил бы, что есть нативная функция MathMin(). Она тоже считает, что нули с разными знаками равны. Насколько понял, то у неё алгоритм достаточно простой. Продублировал его в своей функции CustomMathMin().

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
   {
   double positive_zero_val, negative_zero_val;
   positive_zero_val = 0.0;
   negative_zero_val = -0.0;
   // 1) -0.0 / 0.0
   double native_min_val, custom_min_val;
   native_min_val = ::MathMin(negative_zero_val, positive_zero_val);
   custom_min_val = CustomMathMin(negative_zero_val, positive_zero_val);
   ::Print("\nArguments: -0.0, 0.0");
   ::PrintFormat("Native min value = %0.2f", native_min_val);
   ::PrintFormat("Custom min value = %0.2f", custom_min_val);
   // 2) 0.0 / -0.0
   native_min_val = ::MathMin(positive_zero_val, negative_zero_val);
   custom_min_val = CustomMathMin(positive_zero_val, negative_zero_val);
   ::Print("\nArguments: 0.0, -0.0");
   ::PrintFormat("Native min value = %0.2f", native_min_val);
   ::PrintFormat("Custom min value = %0.2f", custom_min_val);
   }
//+------------------------------------------------------------------+
//| Custom MathMin                                                   |
//+------------------------------------------------------------------+
double CustomMathMin(double  value1, double  value2)
   {
   if(value1 < value2)
      return value1;
   return value2;
   }
//+------------------------------------------------------------------+


В журнале имеем:

2024.01.29 23:49:46.351 c11 (EURUSD,H1) Arguments: -0.0, 0.0
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Native min value = 0.00
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Custom min value = 0.00
2024.01.29 23:49:46.351 c11 (EURUSD,H1) 
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Arguments: 0.0, -0.0
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Native min value = -0.00
2024.01.29 23:49:46.351 c11 (EURUSD,H1) Custom min value = -0.00


Легко заметить, что из двух равных чисел алгоритм возьмёт второе число в виде минимального значения...

Документация по MQL5: Математические функции / MathMin
Документация по MQL5: Математические функции / MathMin
  • www.mql5.com
MathMin - Математические функции - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
fxsaber #:

Вы отказываетесь понимать.

   Print(-0.0<0.0);     // false
   Print(-0.0>0.0);     // false
   Print(-0.0<=0.0);    // true
   Print(-0.0>=0.0);    // true
   Print(-0.0==0.0);    // true

ничего особенного. Просто -0.0==0.0

 
Nikolai Semko #:

ничего особенного. Просто -0.0==0.0

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

template <typename T>
T ToType( const double Num )
{
  union UNION
  {
    T Num1;
    double Num2;
  } Union;
  
  Union.Num2 = Num;
  
  return(Union.Num1);
}

void OnStart()
{
  Print(ToType<long>(MathMin(-0.0, 0.0))); // 0
  Print(ToType<long>(MathMin(0.0, -0.0))); // -9223372036854775808
}
 
fxsaber #:

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

template <typename T>
T ToType( const double Num )
{
  union UNION
  {
    T Num1;
    double Num2;
  } Union;
  
  Union.Num2 = Num;
  
  return(Union.Num1);
}

void OnStart()
{
  Print(ToType<long>(MathMin(-0.0, 0.0))); // 0
  Print(ToType<long>(MathMin(0.0, -0.0))); // -9223372036854775808
}

Ну и что необычного?
То, что в числах 0.0 и -0.0 не все 64 бит одинаковые - это очевидно:


но при этом все равно 0.0 == -0.0

Base Convert: IEEE 754 Floating Point
  • baseconvert.com
Online IEEE 754 floating point converter and analysis. Convert between decimal, binary and hexadecimal
 
Ihor Herasko #:

Знаки < и <= вроде бы разные...

согласен

 
Nikolai Semko # :

Ну и что необычного?
То, что в числах 0.0 и -0.0 не все 64 бит одинаковые - это очевидно :



Он ожидает, что функция MathMin() будет детерминированной. Таким образом, чтобы всегда давать один и тот же результат, когда два аргумента одинаковы. И не разный результат в зависимости от того, какой аргумент первый или второй.

fxsaber прав, это проблема.

 
Alain Verleyen #:

Он ожидает, что функция MathMin() будет детерминированной. Таким образом, чтобы всегда давать один и тот же результат, когда два аргумента одинаковы. И не разный результат в зависимости от того, какой аргумент первый или второй...

А она и есть такая. Когда 2 числа равны, то возвращается второе. Выше на примере показал...

 
   Print(pow(0.0,0.0)); 	// 1.0
   Print(pow(-0.0,-0.0));       // 1.0
   Print(pow(-0.0,0.0));        // 1.0
   Print(pow(0.0,-0.0));        // 1.0
   Print(0.0*-0.0);             // -0.0
   Print(-0.0*-0.0);            // 0.0


и здесь все в порядке.

 
Alain Verleyen #:

Он ожидает, что функция MathMin() будет детерминированной. Таким образом, чтобы всегда давать один и тот же результат, когда два аргумента одинаковы. И не разный результат в зависимости от того, какой аргумент первый или второй.

fxsaber прав, это проблема.

Вы правильно меня поняли. Можно нарваться на трудноуловимое получение разного результата в большом коде. Поэтому уведомил сообщество в этой ветке.

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