Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 242

 
Alain Verleyen #:

Si aspetta che la funzione MathMin() sia deterministica. Quindi che dia sempre lo stesso risultato quando i due argomenti sono uguali. E non un risultato diverso a seconda che l'argomento sia il primo o il secondo.

fxsaber ha ragione, questo è un problema.

ahhh..., allora perché era così confuso su " Matematicamente la stessa espressione (evidenziata) " e l'unione
era sufficiente:

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

ma dal momento che 0.0 == -0.0, allora non riesco a immaginare una situazione in cui questo potrebbe essere un problema e, influenzare qualsiasi cosa

 

una vecchia caratteristica di Min/Max in MQL: funzionano come pensano gli sviluppatori, cioè correttamente :-)

sono gli standard ad essere sbagliati.

 
Nikolai Semko #:

ahhh..., allora perché era così confuso su " Matematicamente la stessa espressione (evidenziata) " e l'unione
era sufficiente:

ma dato che 0.0 == -0.0, non riesco a immaginare una situazione in cui questo possa essere un problema e, di fatto, influire su qualsiasi cosa.

Se non fosse zero, allora sarebbe un problema. E a zero non influisce su nulla.
Per:

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 è la differenza tra -0 e 0? - Stack Overflow




Quindi, tutto ciò che dovete sapere è che 0 = -0
Questa è l'intera caratteristica che non influenza i calcoli e la logica

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

Ho un'ottima comprensione della questione, quindi ho scritto entrambe le versioni di MathMin per dimostrare che funzioni matematicamente identiche nei linguaggi di programmazione producono risultati diversi.

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
}

Sembra che si tratti di un bug.

In C++ funziona bene:

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

nella console:

Long negative zero = 0


Domanda rivolta agli sviluppatori. È normale che nella finestra di debug la variabile Union non si espanda e non reagisca affatto a un clic?


I campi Union.Num1 e Union.Num2 sono stati aggiunti manualmente. Almeno in questo modo si possono vedere i valori...

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

Funziona come previsto! Il primo bit (indice di bit 0) è il bit di segno, che viene impostato per -0,0.

Questi sono anche altri casi speciali nel 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 #:

Sembra che si tratti di un bug.

Funziona bene in C++:

nella console:

non c'è nessun bug. In C ++ è la stessa cosa.
hai semplicemente commesso un errore di formattazione e di tipo

provate questo:

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

Nello stesso contesto, è possibile esaminare la rappresentazione a 64 bit dei doppi 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 versione più breve

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

   return dbl.bits;
  }
 
Nikolai Semko #:

non c'è nessun bug. È lo stesso in C++.
ha solo commesso un errore di formattazione e di tipo.

provate questo:

Sì, ero di fretta. Grazie per la scienza ))

 

A volte è necessario inserire rapidamente un EA nel Tester. Potete farlo in questo modo.

Selezionate una data nel futuro e premete CTRL+F5 in ME.

Motivazione: