WHRoeder: questo codice è buono (soprattutto controlla "added" e "default")? Può anche servire come facile riferimento finale per coloro che visitano questo thread e vanno solo all'ultima pagina (come ho fatto io)
#define LT 0#define GT 1#define GTE 2#define LTE 3#define EQ 4#define NEQ 5bool doublecomp(double a,int type,double b){
// See https://forum.mql4.com/45053/page4// 0 compare doesn't need this functionswitch(type){
case LT: return(b-a>Point/2.);
case GT: return(a-b>Point/2.);
case GTE: return(a-b>-Point); // Addedcase LTE: return(b-a>-Point); // Addedcase EQ: return(!(MathAbs(a-b)>Point/2.));
case NEQ: return(MathAbs(a-b)>Point/2.);
default: return(-1); // Added - needed to avoid compile error about not all control paths returning a value
}
}
SDC: Come si può usare if( !MathAbs( a - b ) > Point/2) per confrontare l'uguaglianza? Questo vi direbbe 1.4999 == 1.5000
Non è così
if( ! (MathAbs( a - b ) > Point/2) ) be used to compare for equality? That would tell you 1.4999 == 1.5000 if( ! (MathAbs(1.4999 - 1.5000 > 0.00005 ) if( ! (0.0001 > 0.00005 ) if( ! (true ) if( false ) 1.4999 is NOT equal to 1.5000
E avevo fatto notare a Roel13 in un PM che il GEQ/LEQ deve essere -Point/2 ma non ha modificato il post
E come ho postato in precedenza, devi preoccuparti di queste sciocchezze solo se l'uguaglianza/non uguaglianza è importante. Se vuoi aprire sopra il massimo di una candela, ha importanza se (a causa dell'arrotondamento) potrebbe scattare esattamente al massimo? Se no basta usare bid > high[].
#define LT 0#define GT 1#define GTE 2#define LTE 3#define EQ 4#define NEQ 5bool ComparePrice(double a,int type,double b){
// See https://forum.mql4.com/45053/page4// 0 compare doesn't need this functionswitch(type){
case LT: return(b-a>Point/2.);
case GT: return(a-b>Point/2.);
case GTE: return(a-b>-Point/2.);
case LTE: return(b-a>-Point/2.);
case EQ: return(!(MathAbs(a-b)>Point/2.));
case NEQ: return(MathAbs(a-b)>Point/2.);
}
return(-1);
}
E, forse una funzione secondaria per confrontare tutti gli altri doppi che non sono prezzi...
bool CompareNormal(double a,int type,double b){
// With thanks https://forum.mql4.com/45053/page4// 0 compare doesn't need this functionswitch(type){
case LT: return(b-a>0.0000000000000000000000000000001);
case GT: return(a-b>0.0000000000000000000000000000001);
case LTE: return(b-a>-0.0000000000000000000000000000001);
case GTE: return(a-b>-0.0000000000000000000000000000001);
case EQ: return(!(MathAbs(a-b)>0.0000000000000000000000000000001));
case NEQ: return(MathAbs(a-b)>0.0000000000000000000000000000001);
}
return(-1);
}
Vedi anche 'MQL4 Reference > Language Basics > Data Types > Real Types (double, float)' per quanto riguarda l'uso di numeri piccoli per il confronto.
Forse qualcuno sa come scrivere meglio 0.00...1 in expon
Notate che il valore di epsilon nell'esempio precedente non può essere inferiore alla costante predefinita DBL_EPSILON. Il valore di questa costante è 2.2204460492503131e-016.
Di nuovo, niente di tutto questo è necessario, tranne nel caso in cui l'uguale/non uguale è importante. Ad esempio, se si apre sopra il massimo precedente, non si vuole aprire al massimo a causa dell'arrotondamento.
Quindi c'è qualcos'altro di interessante che ho trovato, potenzialmente in connessione con "// 0 compare non ha bisogno di questa funzione".
Forse un bug solo nelle ultime versioni, non sono sicuro. Il confronto con 0 non funziona più correttamente. Ho dovuto ricorrere a qualcosa di poco amichevole come
Penso che questo argomento sia trattato con troppa complessità inutile.
Cercate di rendere la vita del vostro programmatore sempre più facile possibile. Scrivete delle definizioni (o andate avanti con i metodi se proprio dovete) in quelle classi dove avete bisogno dei vostri doppi confronti:
// add more floating point zeros if you need a higher precision
#define isZero(x) (fabs(x) < 0.000000001)
#define isEqual(x,y) (fabs(x-y) < 0.000000001)
Quando hai bisogno di confrontare due doppi allora usalo in una condizione come questa:
if (isEqual(myFirstDouble, mySecondDouble))
{
// first and second doubles are considered equal// do something
}
Se volete vedere se un doppio è zero (o molto, molto vicino allo zero) usate una condizione come questa:
if (isZero(myDouble))
{
// myDouble is considered zero// do something
}
Una nota a margine, dato che vedo molti post che parlano di divisioni:
Con l'incapsulamento tendiamo a dimenticare i costi del codice che viene "esternalizzato" ad alcuni metodi di utilità. Ricordatevi chele divisioni sono computazionalmente molto costose! Soprattutto, una volta avvolte in bei metodi di utilità da qualche parte nelle classi di utilità, cominciamo ad usarle ovunque negli indicatori o negli EA e ci siamo dimenticati da tempo quali passi computazionali eseguono. Quando usiamo lo strategy tester paghiamo un sacco di tempo inutile per la nostra sciatteria.
Regola empirica: Addizioni e sottrazioni sono molto più veloci di moltiplicazioni e divisioni. L'operazione di divisione richiede il tempo di calcolo più alto.Ottimizzate le divisioni- dove possibile! Se il denominatore è fisso come in questo ciclo...
allora sostituisci il denominatore x con il suo valore invertito 1/x:
for(int i=0; i < rates_total; i++)
{
// ...double fraction = 0.01 * someNumeratorValue; // replace a denominator with it's inverted value, if possible.
// ...
}
Inoltre, se il risultato di una divisione è sempre lo stesso, allora fai il calcolo una volta sola e salva il risultato in una variabile in modo da poterlo usare ovunque nel tuo codice (ad esempio nei loop):
double tradesPerDay = totalTradesPerYear/365;
for(int i=0; i < rates_total; i++)
{
// use precomputed tradesPerDay rather than computing the division here.
}
WHRoeder: questo codice è buono (soprattutto controlla "added" e "default")? Può anche servire come facile riferimento finale per coloro che visitano questo thread e vanno solo all'ultima pagina (come ho fatto io)
Quel codice non è accurato.
Come si può usare if( !MathAbs( a - b ) > Point/2) per confrontare per l'uguaglianza? Questo vi direbbe 1.4999 == 1.5000
if( ! (MathAbs(1.4999 - 1.5000 > 0.00005 )
if( ! (0.0001 > 0.00005 )
if( ! (true )
if( false ) 1.4999 is NOT equal to 1.5000
Io uso
o per i doppi che non sono prezzi reali, una maggiore precisione
Il post di Raptors su questo codice
Quindi se usate,
Ho testato quel metodo in vari modi e non ho trovato uno scenario in cui non restituisse il risultato atteso o desiderato.Codice finale... Grazie WHRoeder
E, forse una funzione secondaria per confrontare tutti gli altri doppi che non sono prezzi...
Vedi anche 'MQL4 Reference > Language Basics > Data Types > Real Types (double, float)' per quanto riguarda l'uso di numeri piccoli per il confronto.
Forse qualcuno sa come scrivere meglio 0.00...1 in expon
Quindi c'è qualcos'altro di interessante che ho trovato, potenzialmente in connessione con "// 0 compare non ha bisogno di questa funzione".
Forse un bug solo nelle ultime versioni, non sono sicuro. Il confronto con 0 non funziona più correttamente. Ho dovuto ricorrere a qualcosa di poco amichevole come
risultato=(int(risultato*100)/100.0); // Risoluzione 2 cifre
Solo per assicurarmi che i valori 0 finissero effettivamente come valori 0.
WHRoeder, grazie. Più studio necessario :)
Penso che questo argomento sia trattato con troppa complessità inutile.
Cercate di rendere la vita del vostro programmatore sempre più facile possibile. Scrivete delle definizioni (o andate avanti con i metodi se proprio dovete) in quelle classi dove avete bisogno dei vostri doppi confronti:
Quando hai bisogno di confrontare due doppi allora usalo in una condizione come questa:
Se volete vedere se un doppio è zero (o molto, molto vicino allo zero) usate una condizione come questa:
Una nota a margine, dato che vedo molti post che parlano di divisioni:
Con l'incapsulamento tendiamo a dimenticare i costi del codice che viene "esternalizzato" ad alcuni metodi di utilità. Ricordatevi chele divisioni sono computazionalmente molto costose! Soprattutto, una volta avvolte in bei metodi di utilità da qualche parte nelle classi di utilità, cominciamo ad usarle ovunque negli indicatori o negli EA e ci siamo dimenticati da tempo quali passi computazionali eseguono. Quando usiamo lo strategy tester paghiamo un sacco di tempo inutile per la nostra sciatteria.
Regola empirica: Addizioni e sottrazioni sono molto più veloci di moltiplicazioni e divisioni. L'operazione di divisione richiede il tempo di calcolo più alto.Ottimizzate le divisioni- dove possibile! Se il denominatore è fisso come in questo ciclo...
allora sostituisci il denominatore x con il suo valore invertito 1/x:
Inoltre, se il risultato di una divisione è sempre lo stesso, allora fai il calcolo una volta sola e salva il risultato in una variabile in modo da poterlo usare ovunque nel tuo codice (ad esempio nei loop):
Grazie,
A.T.