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

 
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.

ahhh..., entonces por que era tan confuso lo de " Matematicamente la misma expresion (resaltada) " y la union
era suficiente:

Print(MathMin(-0.0, 0.0)); // 0.0
Print(MathMin(0.0, -0.0)); // -0.0

pero desde 0.0 == -0.0, entonces no puedo imaginar una situación en la que esto podría ser un problema y, afectar a nada en absoluto

 

una vieja característica de Min/Max en MQL - funcionan como los desarrolladores piensan, es decir, correctamente :-)

son las normas las que están equivocadas.

 
Nikolai Semko #:

ahhh..., entonces por qué era tan confuso lo de " Matemáticamente la misma expresión (resaltada) " y la unión
era suficiente:

pero desde 0.0 == -0.0, entonces no puedo imaginar una situación en la que esto podría ser un problema y, de hecho, afectar a nada en absoluto

Si no fuera cero, entonces sería un problema. Y en cero no afecta a nada.
Para:

x * 0.0 = 0.0
x * -0.0 = -0.0
x + -0.0 = x
x - -0.0 = x
pow(x,-0.0) = 1
log(0.0)  // -inf
log(-0.0)  // -inf
 

c++ - ¿Cuál es la diferencia entre -0 y 0? - Stack Overflow




Por lo tanto, todo lo que necesitas saber es que 0 = -0
Esa es toda la característica que no afecta a los cálculos y la lógica

What is the difference between -0 and 0?
What is the difference between -0 and 0?
  • 2010.09.14
  • Danvil Danvil 22.5k 20 20 gold badges 66 66 silver badges 90 90 bronze badges
  • stackoverflow.com
In C++, for example returns . The expression is true, but the bits are different. What is the purpose of having something like which should be but is represented differently? Is used exactly the same way as in any computations?
 
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
}

Parece ser un error.

Funciona bien en C++:

#include <iostream>

using namespace std;
//
template <typename T>
T ToType(const double Num)
{
    union UNION
    {
        T Num1;
        double Num2;
    } Union;
    Union.Num2 = Num;
    return(Union.Num1);
}
//
int main()
{
    double positive_zero_val, negative_zero_val;
    positive_zero_val = 0.0;
    negative_zero_val = -0.0;
    //---
    long long_negative_zero_val = ToType<long>(negative_zero_val);
    printf("\nLong negative zero = %d", long_negative_zero_val);
    cin.get();
}

en la consola:

Long negative zero = 0


Pregunta de pasada a los desarrolladores. ¿Es normal que en la ventana de depuración la variable Union no se expanda y no reaccione en absoluto a un clic?


Los campos Union.Num1 y Union.Num2 se añadieron manualmente. Al menos así se pueden ver los valores...

 
string DoubleToHexadecimal(const double value)
  {
   return StringFormat("0x%.16llX", value);
  }

void OnStart()
  {
   Print(DoubleToHexadecimal(0.0) );    // 0x0000000000000000   (i.e, long integer 0)
   Print(DoubleToHexadecimal(-0.0) );   // 0x8000000000000000   (i,e, LONG_MIN -9223372036854775808)
  }
  

Funciona como se esperaba. El primer bit (índice de bits 0) es el bit de signo que se establece para -0,0.

Estos son también más casos especiales en el formato ieee 754. https://www. wikiwand.com/en/IEEE%20754#Special_values

void OnStart()
  {
   const double Nan = (double)"nan";
   const double Inf = (double)"inf";

   Print( MathMin(Nan, Inf));   // inf
   Print( MathMin(Inf, Nan));   // nan

   Print( MathMin(Nan, 0));     // 0.0
   Print( MathMin(0, Nan));     // nan
  }
 
Denis Kirichenko #:

Parece ser un error.

Funciona bien en C++:

en la consola:

no hay ningún error. En C++ es lo mismo.
sólo cometiste un error con el formato y el tipo

prueba esto:

#include <iostream>

using namespace std;
//
template <typename T>
T ToType(const double Num)
{
    union UNION
    {
        T Num1;
        double Num2;
    } Union;
    Union.Num2 = Num;
    return(Union.Num1);
}
//
int main()
{
    double positive_zero_val, negative_zero_val;
    positive_zero_val = 0.0;
    negative_zero_val = -0.0;
    //---
    long long  long_negative_zero_val = ToType<long long>(negative_zero_val);
    printf("\nLong negative zero = %ll d", long_negative_zero_val);
}
 

En el mismo contexto, puede examinar la representación de 64 bits de los dobles https://www.mql5.com/en/code/20822

//+------------------------------------------------------------------+
//| Returns the bit representation corresponding to a double value . |
//+------------------------------------------------------------------+
long DoubleToLongBits(const double value)
  {
   union _d {double value; long bits;} dbl;
   dbl.value = value;

   return dbl.bits;
  }

o la versión abreviada

long DoubleToLongBits(const double value)
  {
   union _d {double value; long bits;} dbl = { value };

   return dbl.bits;
  }
 
Nikolai Semko #:

no hay ningún error. Es lo mismo en C++.
sólo cometió un error con el formato y el tipo

prueba esto:

Sí, yo estaba en un apuro. Gracias por la ciencia ))

 

A veces es necesario poner rápidamente un EA en el Probador. Puede hacerlo de la siguiente manera

Seleccione una fecha en el futuro y pulse CTRL+F5 en ME.