Características da linguagem mql5, subtilezas e técnicas - página 242

 
Alain Verleyen #:

Ele espera que a função MathMin() seja determinística. Portanto, que sempre forneça o mesmo resultado quando os dois argumentos forem os mesmos. E não um resultado diferente dependendo de qual argumento é o primeiro ou o segundo.

fxsaber está certo, isso é um problema.

ahhh..., então por que estava tão confuso sobre " Mathematically the same expression (highlighted) " e union
foi suficiente:

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

mas como 0,0 == -0,0, não consigo imaginar uma situação em que isso possa ser um problema e afetar alguma coisa

 

um recurso antigo do Mín/Máx no MQL - eles funcionam da maneira que os desenvolvedores pensam, ou seja, corretamente :-)

são os padrões que estão errados.

 
Nikolai Semko #:

ahhh..., então por que estava tão confuso sobre " Mathematically the same expression (highlighted) " e a união
foi suficiente:

mas como 0,0 == -0,0, não consigo imaginar uma situação em que isso possa ser um problema e, de fato, afetar alguma coisa

Se não fosse zero, então seria um problema. E em zero não afeta 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++ - Qual é a diferença entre -0 e 0? - Stack Overflow




Portanto, tudo o que você precisa saber é que 0 = -0
Esse é o recurso completo que não afeta os cálculos e a 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 #:

Como tenho um excelente entendimento da questão, escrevi as duas versões do MathMin para mostrar que funções matematicamente idênticas em linguagens de programação produzem 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 um bug.

Ele funciona bem em 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();
}

no console:

Long negative zero = 0


Pergunta para os desenvolvedores. É normal que, na janela de depuração, a variável Union não se expanda e não reaja a um clique?


Os campos Union.Num1 e Union.Num2 foram adicionados manualmente. Pelo menos dessa forma você pode ver os 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 esperado! O primeiro bit (índice de bit 0) é o bit de sinal que é definido para -0,0.

Esses também são casos mais especiais no 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 um bug.

Ele funciona bem em C++:

no console:

não há nenhum erro. Em C++ é a mesma coisa.
você cometeu apenas um erro de formatação e digitação

tente isso:

#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);
}
 

No mesmo contexto, isso pode examinar a representação de 64 bits de duplas 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;
  }

ou a versão mais curta

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

   return dbl.bits;
  }
 
Nikolai Semko #:

Não há nenhum erro. É o mesmo em C++.
apenas cometeu um erro de formatação e tipo

tente isso:

Sim, eu estava com pressa. Obrigado pela ciência ))

 

Às vezes, você precisa colocar rapidamente um EA no testador. Você pode fazer isso da seguinte forma.

Selecione uma data no futuro e pressione CTRL+F5 no ME.