Características del lenguaje mql5, sutilezas y técnicas - página 241

 
fxsaber #:

Te niegas a entender.

Tal vez lo haría si conociera el trasfondo de la situación. Pero tal como está, parece correcto.

 
amrali #:

Mientras las dos cantidades sean iguales, cualquiera de ellas es un mínimo válido. Considere MathMin(1, 1), no difiere si la función devuelve el primero (1) o el segundo (1).

Por lo tanto, devolver 0.0 no es diferente de -0.0.

Edición: por cierto, las dos expresiones resaltadas NO son idénticas.

Creo que estoy de acuerdo con mi colega amrali. También añadiría que existe una función nativa MathMin(). También piensa que los ceros con distinto signo son iguales. Por lo que tengo entendido, su algoritmo es bastante sencillo. Lo he duplicado en mi función 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;
   }
//+------------------------------------------------------------------+


Lo tenemos en el registro:

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


Es fácil ver que a partir de dos números iguales, el algoritmo tomará el segundo número como valor mínimo de...

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

Te niegas a entender.

   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

no es nada especial. Sólo -0.0==0.0.

 
Nikolai Semko #:

nada especial. Sólo -0.0==0.0

Conozco muy bien la pregunta, así que escribí ambas variantes de MathMin para demostrar que funciones matemáticamente idénticas en lenguajes de programación producen resultados diferentes.

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 #:

Por eso escribí ambas versiones de MathMin para demostrar que funciones matemáticamente idénticas en lenguajes de programación producen resultados diferentes.

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
}

Entonces, ¿qué es lo inusual?
El hecho de que en los números 0.0 y -0.0 no todos los 64 bits son iguales es obvio:


pero aún así 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 #:

Los signos < y <= parecen ser diferentes.....

de acuerdo

 
Nikolai Semko # :

Entonces, ¿qué es lo inusual?
El hecho de que en los números 0,0 y -0,0 no todos los 64 bits sean iguales es obvio:



Espera que MathMin() sea determinista. Es decir, que dé siempre el mismo resultado cuando los dos argumentos son iguales. Y no un resultado diferente dependiendo de qué argumento es el primero o el segundo.

fxsaber tiene razón, esto es un problema.

 
Alain Verleyen #:

Espera que la función MathMin() sea determinista. Es decir, que dé siempre el mismo resultado cuando los dos argumentos sean iguales. Y no un resultado diferente dependiendo de qué argumento es el primero o el segundo....

Y así es. Cuando 2 números son iguales, se devuelve el segundo. Lo he mostrado arriba con un ejemplo...

 
   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


y no hay nada malo en ello.

 
Alain Verleyen #:

Espera que la función MathMin() sea determinista. Es decir, que dé siempre el mismo resultado cuando los dos argumentos sean iguales. Y no un resultado diferente dependiendo de qué argumento es el primero o el segundo.

fxsaber tiene razón, esto es un problema.

Me ha entendido bien. Puedes encontrarte con el problema de obtener resultados diferentes en código grande. Por eso avisé a la comunidad en este hilo.