Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 241

 
fxsaber #:

Vi rifiutate di capire.

Forse lo farei se conoscessi il contesto della situazione. Ma così com'è, sembra giusto.

 
amrali #:

Finché le due quantità sono uguali, una qualsiasi di esse è un minimo valido. Consideriamo MathMin(1, 1), non fa differenza se la funzione restituisce il primo (1) o il secondo (1).

Quindi, restituire 0,0 non è diverso da -0,0.

Modifica: a proposito, le due espressioni evidenziate NON sono identiche.

Credo di essere d'accordo con il collega amrali. Vorrei anche aggiungere che esiste una funzione nativa MathMin(). Anch'essa pensa che gli zeri con segni diversi siano uguali. Per quanto ne so, il suo algoritmo è piuttosto semplice. L'ho duplicato nella mia funzione 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 vediamo nel log:

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


È facile vedere che da due numeri uguali, l'algoritmo prenderà il secondo numero come valore minimo di...

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

Vi rifiutate di capire.

   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

non è niente di speciale. Solo -0,0==0,0.

 
Nikolai Semko #:

niente di speciale. Solo -0,0==0,0

Conosco bene la domanda, quindi ho scritto entrambe le varianti 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
}
 
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
}

Cosa c'è di strano?
Il fatto che nei numeri 0,0 e -0,0 non tutti i 64 bit siano uguali è ovvio:


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

I segni < e <= sembrano essere diversi.....

concordare

 
Nikolai Semko # :

Cosa c'è di insolito?
Il fatto che nei numeri 0,0 e -0,0 non tutti i 64 bit siano uguali è ovvio:



Si aspetta che MathMin() sia deterministico. 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.

 
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....

Ed è così. Quando due numeri sono uguali, viene restituito il secondo. Ho mostrato sopra un esempio...

 
   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


e non c'è niente di male in questo.

 
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.

Ha capito bene il mio punto di vista. Si può incorrere nel problema difficile da trovare di ottenere risultati diversi in un codice di grandi dimensioni. Ecco perché ho informato la comunità in questo thread.

Motivazione: