Errori, bug, domande - pagina 2821

 
Igor Makanu:

la normalizzazione non è l'arrotondamento

Ho un A+ in teoria, come lavorare con il doppio e così via. L'algoritmo NormalizeDouble contiene un errore. L'argomento sollevato è solo indirettamente legato al confronto dei doppi.

 
fxsaber:

Ripeto la mia domanda.

L'immagine mostra il valore della variabile non normalizzata n e della variabile normalizzata m e quanto sono diversi. Ma se vuoi confrontare i tanga, è la tua preferenza.

fxsaber:

Conosco la teoria, come lavorare con il doppio e cose del genere su una scala A+. L'algoritmo NormalizeDouble contiene un errore. L'argomento sollevato è solo indirettamente legato al confronto dei doppi.

Sicuramente non si può fare a meno della spiegazione di Semko qui.
 
NormalizeDouble è solo un certo algoritmo che si applica a un numero doppio. Purtroppo c'è un errore. Se corretto, l'errore scomparirà. La doppia rappresentazione di tutti gli altri non cambierà in alcun modo.
 
fxsaber:

L'algoritmo NormalizeDouble contiene un errore.

Credo che A100 ne abbia scritto

ma gli sviluppatori da MQL si sono attenuti a questa "caratteristica", ahimè


fxsaber:
Se lo correggono, l'errore sparirà.
Penso che ci saranno altri bug e ci sarà molto rumore ))))
 
Igor Makanu:

Penso che altri bug appariranno e ci sarà molto rumore ))))

Non lo faranno, perché quasi tutti confrontano anche i dub normalizzati attraverso la normalizzazione. Cioè lo mettono dove vogliono.


Una corretta normalizzazione dovrebbe dare sempre vero in questa condizione.

Forum sul trading, sistemi di trading automatico e test di strategia

Errori, bug, domande

fxsaber, 2020.08.10 11:37

  Print((double)(string)Norm == Norm);    // false

Questo è l'unico controllo che la normalizzazione sia corretta. Se darà sempre la verità, niente si romperà.

 
fxsaber:
NormalizeDouble è solo un certo algoritmo che si applica a un numero doppio. Purtroppo c'è un errore. Se corretto, l'errore scomparirà. Tutte le altre doppie rappresentazioni non cambieranno di conseguenza.
Penso che non si tratti della funzione, ma che le costanti non sono normalizzate dal compilatore (anche se dovrebbero esserlo).
Lo stesso vale per la conversione di una stringa in un doppio.
 
Alexey Navoykov:
Penso che non si tratti della funzione, ma che le costanti non siano normalizzate dal compilatore (anche se dovrebbero esserlo).
Lo stesso vale per la conversione da stringa a doppia.

Allora le stesse costanti in DLL e MQL non corrisponderanno.

 
fxsaber:

Allora le stesse costanti in DLL e MQL non corrisponderanno.

Anche vero. Inoltre qualsiasi normalizzazione è una perdita di precisione, quindi potrei aver esagerato con la normalizzazione delle costanti.
In generale, questo problema, secondo me, non ha una soluzione univoca, anche se in realtà non è un problema.
 
Alexey Navoykov:
Anche vero. Inoltre, ogni normalizzazione è una perdita di precisione, quindi probabilmente sto esagerando con la normalizzazione costante.
In generale, questo problema non mi sembra avere una soluzione univoca, anche se in sostanza non è un problema.

Basta modificare l'attuale algoritmo di normalizzazione.

 
fxsaber:

Basta modificare l'attuale algoritmo di normalizzazione.

void OnStart() {
   double d1=1.79435;
   double d2=NormalizeDouble(1.79435,5);
   Print(d1==d2);
   Print(is_equal(d1,d2,_Point/2));
}
//+------------------------------------------------------------------+
bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}

Non so nemmeno se questo è un bug nell'algoritmo.
Davvero, non si possono paragonare i doppi. Solo una regola ferrea.
O, come dice Slava, attraverso l'epsilon o attraverso la moltiplicazione (ad esempio per 1/_Point) con conversione in int con arrotondamento.

Solo l'arrotondamento non è fatto da round(), ceil(), floor() perché anche loro restituiscono doppio.

O attraverso questi, soprattutto perché lavorano più velocemente di quelli normali:

int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;}
int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);}
int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;}

Più facile e più veloce, naturalmente, attraverso epsilon:

bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}
Motivazione: