Domanda ai maestri di MQL4. Di nuovo a proposito di Double Compare.

 
Ciao!
Come sapete, non solo la correttezza dei calcoli ma anche l'affidabilità del codice scritto dipende dallo stile di programmazione e dalla pulizia del codice.
Noi non scriviamo giocattoli, quindi l'affidabilità del programma scritto è il primo requisito. La maggior parte dei calcoli sono eseguiti in duble e un confronto corretto di due reali
di due numeri reali nel codice del programma richiede un certo approccio e precisione.
Sto cercando di capire lo stile di programmazione "giusto", da qui la domanda:

Per un'espressione

doppio a;
doppio b;

se(a==b) o se(a!=b)
{......} {......}

Gli sviluppatori raccomandano questo
//+------------------------------------------------------------------+
//| Funzione di confronto di due numeri reali.
//+------------------------------------------------------------------+
bool CompareDouble(double Number1, double Number2)
{
bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
ritorno(Compare);
}
//+------------------------------------------------------------------+


Questo codice è corretto?

doppio a;
doppio b;

se(a>b) se(a<b)
{......} {......}


Molto probabilmente non nel caso generale. Qual è il modo corretto di controllarlo?
In generale, quale stile di lavoro con i dubles è più appropriato?
Grazie in anticipo a tutti coloro che rispondono.
 

Preferisco usare le cifre più grandi e più piccole per il confronto quando è possibile,

double a;
double b;
 
if(a>b)             if(a<b)
    {......}            {......}

in modo da non dovermi preoccupare troppo di correre il doppio fino a una certa cifra

Vol = 156.00000002; 
NormVol = NormalizeDouble(Vol,2); 
156.00

Se è necessario mettere insieme i numeri

if(a==b)    или         if(a!=b)
    {......}                    {......}

poi prima converto entrambi i numeri in una sola cifra dopo il punto

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......}
 
xeon:

Prima converto entrambi i numeri nella stessa cifra dopo il punto

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
E quando calcolate negli indicatori usate Normalize e preparazioni simili?
Sto guardando un sacco di codice, sto imparando a programmare e raramente si trova nel codice dell'indicatore. Questo è il problema - come farlo correttamente.
 
VBAG:
xeon:

Prima converto entrambi i numeri nella stessa cifra dopo il punto

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
Usate Normalize e preparazioni simili nei vostri calcoli di indicatori?
Sto guardando un sacco di codice, sto imparando a programmare e raramente si trova nel codice dell'indicatore. Questo è il problema - come farlo correttamente.

Cerco di evitarlo usandoNormalizeDouble o i segni "<" e ">", perché l'indicatore, lo script o Expert Advisor può avere discrepanze nel doppio.
 
xeon ,
Grazie per la vostra opinione.
 
Normalizzare sempre e non ci sarà mai un problema con i dubs! ;)
In qualsiasi confronto, qualsiasi dabbenaggine, e con una precisione volutamente scelta.

//--- NormalizeDouble
double nd( double value, int precision )
{
    return( NormalizeDouble( value, precision ) );
}
 
//--- MathAbs
double abs( double value )
{
    return( MathAbs( value ) );
}
 
//--- Если value1 равняется value2 до precision знака после запятой, возвращает true, иначе - false.
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( nd( value1, precision ) - nd( value2, precision ) ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}

Fate attenzione alla funzione uguale - se cambiata leggermente:
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( value1 - value2 ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}
(rimuovere la normalizzazione di ogni numero prima del confronto), darà un risultato diverso.

Per esempio, equal( 0.123456784, 0.123456776 ) restituirà true nel primo caso, ma false nel secondo ;)
 
komposter:
Normalizzare sempre e non ci sarà mai un problema con i dubs! ;)
Ma ci saranno problemi di prestazioni. Il problema di confrontare i numeri a doppia precisione è inverosimile e viene dall'ignoranza di base della matematica.
 
Irtron:
Il problema di confrontare i numeri a doppia precisione è inverosimile e viene dall'ignoranza di base della matematica.

Lasciatemi spiegare.

Ovviamente, c'è una confusione di nozioni. C'è un tipo di numero in virgola mobile utilizzato nell'architettura intel per rappresentare i numeri a precisione fissa, che, in particolare, includono tutti i valori dell'ambiente di trading, poiché il processore ha una trebbiatrice speciale per l'aritmetica in virgola mobile.

In effetti, i numeri a precisione fissa differiscono molto poco dagli interi in termini di rappresentazione meccanica. La presenza di un decimale in questo caso è condizionale. Questa proprietà è ampiamente utilizzata in architetture in cui l'aritmetica in virgola mobile non è supportata dall'hardware, come ARM, che si è diffusa attraverso l'uso in PDA e smartphone. L'aritmetica fluttuante deve essere emulata con un codice piuttosto pesante, che riscalda il processore e quindi spreca la batteria, per non parlare della velocità di esecuzione del programma. Quindi, ogni volta che non è possibile fare con i numeri interi, si usa un formato fisso. La precisione fluttuante è usata nei casi più estremi. O piuttosto, naturalmente, dovrebbe esserlo.

Nulla impedisce l'uso dell'aritmetica fissa (cioè intera) per i valori di mercato.

Questo non si applica ai valori calcolati degli indicatori. Un confronto diretto è abbastanza sufficiente. Perché confrontarli con precisione?
 
Grazie a komposter e Irtron! Ho già deciso che non si scriverà più nulla e mi sono seduto per inventare me stesso e non ho visto i vostri post.
Vedete cosa ho scritto con la mia mano astuta:
//+------------------------------------------------------------------+
bool EqualDouble(double dN1, double dN2,int Digit)
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 == 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool LessDouble(double dN1, double dN2,int Digit) // Se dN1<dN2
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d2-d1 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool MoreDouble(double dN1, double dN2,int Digit) // Se dN1>dN2
{
double d1 = NormalizeDouble(dN2,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
Покритикуйте, пожалуйста.
 
VBAG:
Vi prego di vedere cosa ho scarabocchiato con la mia mano sciatta:
Quali valori state cercando di confrontare? Prezzi, lotti o valori dell'indicatore?
 
Irtron:
VBAG:
Per favore, date un'occhiata a quello che ho scarabocchiato con la mia mano sciatta:
Quali valori state cercando di confrontare? Prezzi, lotti o valori dell'indicatore?
Ho scritto all'inizio: "Cercando di ottenere il 'giusto' stile di programmazione. "
In sostanza, non fa differenza cosa c'è nei doppioni - solo la precisione dell'arrotondamento di Digit varierà, a seconda dei requisiti della variabile.