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

 
SK. писал (а):

Questa conversazione sembra continuare all'infinito. Quando un nuovo utente ha acquisito la giusta esperienza e conoscenza, di solito ha il tempo di imbattersi nella normalizzazione diverse volte.

Forse in MT5 ha senso limitare forzatamente la precisione dei numeri reali quando si eseguono operazioni di confronto, per esempio, a 8 cifre decimali (cioè eseguire forzatamente NormalizeDouble() con digit=8).

Non me lo aspetterei da te. Assolutamente no!
Se l'operazione di confronto sarà usata ripetutamente (nei calcoli ricorrenti, ecc.), allora arrotondando a 8 cifre in ingresso, l'errore in uscita può essere commisurato a 1.

Ho avuto un'esperienza simile con il calcolo di SmoothedAvarege, calcolandolo nella mia applicazione un anno fa. Dopodiché, sto cercando di scegliere dei metodi di lavoro che non incidano sulla capacità numerica dei doppi.
Oppure, come ha suggerito gravity001 , passare a INTam (che, come si capisce, richiede molto tempo).
 
SK. писал (а):

Forse in MT5 ha senso limitare forzatamente la precisione dei numeri reali quando si eseguono operazioni di confronto a, diciamo, 8 cifre decimali (cioè eseguire forzatamente NormalizeDouble() con digit=8).


Tuttavia, non solo le operazioni definite dall'utente rallentano il terminale, ma anche le operazioni nascoste da esso. Mi sembra preferibile introdurre semplicemente la funzione ComparePrice nel linguaggio. A proposito, proprio come Irtron, considero Punto/2 una misura naturale (forse meglio Punto *0,5). Per evitare di dividere/moltiplicare ogni volta, questa metà può essere resa una variabile predefinita. Finché non esiste, potete inserire voi stessi una tale variabile e calcolarla una volta al primo avvio. Anche se gli sviluppatori possono fare la funzione di confronto doppio con precisione predefinita, cioè la stessa, ma con cifre invece di Punto/2.
 
Depfy:

Hai fatto un pasticcio... :)

Il confronto dei numeri fluttuanti è fatto confrontando il modulo della differenza con una piccola soglia.

Restituisce (fabs(d1-d2) < 1e-10) per esempio.

Che senso ha confondere le acque... La funzione NormalizeDouble(...) è solo per rapporti dall'aspetto gradevole.

Grazie per l'esempio.
Ma non hai capito il punto, devi leggere con più attenzione. L'essenza della domanda è lo stile di programmazione in generale, e nel caso specifico di MT4.
 
VBAG:
Depfy:

Hai fatto un casino di cose... :)

Il confronto dei numeri fluttuanti è fatto confrontando il modulo della differenza con una piccola soglia.

Restituisce (fabs(d1-d2) < 1e-10) per esempio.

Che senso ha confondere le acque... La funzione NormalizeDouble(...) è solo per rapporti dall'aspetto gradevole.

Grazie per l'esempio.
Ma non hai capito il punto, devi leggere con più attenzione. L'essenza della domanda è lo stile di programmazione in generale, e nel caso specifico di MT4.

Faresti meglio a dirci qual è il senso di questa domanda. Altrimenti suggerimenti - non capisco :)

Se parliamo di velocità, i processori moderni eseguono operazioni in virgola mobile

quasi quanto quelli interi. Per quanto riguarda lo STILE, mi dispiace, il pragmatismo regna...

Quando ci sono gli ASHIPS, di che tipo di stile stiamo parlando... Basta che funzioni. ...

Altrimenti non c'è altro problema che confrontare due numeri :))))))))

 
VBAG:
Non mi aspettavo niente del genere da te. Non devi farlo in ogni caso!
Se l'operazione di confronto sarà usata ripetutamente (in calcoli ricorrenti, ecc.), allora arrotondando a 8 cifre in ingresso, l'errore in uscita può essere commisurato a 1.

Ho avuto un'esperienza simile con il calcolo di SmoothedAvarege, calcolandolo nella mia applicazione un anno fa. Dopodiché, sto cercando di scegliere dei metodi di lavoro che non incidano sulla capacità numerica dei doppi.
Oppure, come ha suggerito gravity001 , passare a INTam (che, come si capisce, richiede molto tempo).


Aspetta un attimo. Non c'è bisogno di saltare alle conclusioni.

In primo luogo. Non propongo di arrotondare forzatamente il valore reale della variabile reale stessa. Propongo di forzare l'arrotondamento dei valori confrontati (copie) delle variabili quando si calcola il risultato di un'operazione di confronto (per il caso predefinito). E naturalmente, il valore reale della variabile non deve essere toccato. In questo caso, nessun altro valore calcolato verrebbe influenzato, perché i valori originali delle variabili utilizzate nelle operazioni di confronto conservano i loro valori, e gli errori nei calcoli ciclici non si accumulerebbero.

Secondo. Ho detto che per eliminare gli errori con conseguenze più dure, possiamo andare in questo modo. Tuttavia, per fornire anche calcoli più impegnativi, è necessario conservare la possibilità di utilizzare la funzioneNormalizeDouble() con parametri specificati.

Quindi il mio suggerimento non limita le capacità del linguaggio, ma le estende.

Tuttavia, tenendo conto che nelle operazioni di confronto, di regola, si usano valori di prezzo (cioè cifra = 4), nella grande maggioranza dei casi questo errore semplicemente non si verificherà. Così, l'utilizzo della tecnologia proposta ridurrà il numero di errori che portano a conseguenze imprevedibili.

 
lna01:
E mentre questo non è disponibile, è possibile inserire una tale variabile e calcolarla una volta al primo avvio dell'avvio.

Non si può.

O meglio, si possono scrivere stringhe di programma, ma nessuno (compresi gli sviluppatori) garantirà che il valore di questa variabile rimarrà rigorosamente invariato per tutta la durata dell'EA. Non si tratta della precisione del codice del programma, ma delle caratteristiche tecnologiche dei calcoli e delle regole tecnologiche di memorizzazione dei valori delle variabili. Se non fosse così, questo problema non esisterebbe nemmeno.

Allo stato attuale, il valore iniziale della variabile 123.00000000000 può apparire come 122.99999999999999 nel momento in cui viene utilizzato nei calcoli. Questo nonostante il fatto che il valore della variabile non sia mai cambiato da quando è stata creata e sia stata chiamata dal programma solo per partecipare ad altri calcoli.

Questo è in realtà il motivo per cui c'è stato tutto questo trambusto. Questo è il motivo per cui abbiamo creato la necessità di usare NormalizeDouble() il più vicino possibile al calcolo effettivo, preferibilmente direttamente nella condizione di if, for, while statements.

 
SK. писал (а):
lna01:
E mentre questo non è disponibile, potete inserire voi stessi una tale variabile e calcolarla una volta al primo avvio dell'avvio.

Non si può.

O meglio, si possono scrivere stringhe di programma, ma nessuno (compresi gli sviluppatori) garantisce che il valore di questa variabile rimarrà rigorosamente invariato per tutta la durata dell'EA. Non si tratta della precisione del codice del programma, ma delle caratteristiche tecnologiche dei calcoli e delle regole tecnologiche per la memorizzazione dei valori delle variabili. Se non fosse così, questo problema non esisterebbe nemmeno.

Allo stato attuale, il valore iniziale della variabile 123.00000000000 può apparire come 122.99999999999999 nel momento in cui viene utilizzato nei calcoli. Questo nonostante il fatto che il valore della variabile non sia mai cambiato da quando è stata creata e sia stata chiamata dal programma solo per partecipare ad altri calcoli.

Questo è in realtà il motivo per cui c'è stato tutto questo trambusto. Ecco perché avevo bisogno di usare NormalizeDouble() il più vicino possibile al calcolo effettivo, preferibilmente proprio nella condizione di if, for, while statements.

Perbacco, credo di cominciare a capire il perché di tutto questo trambusto...

Tutto sommato, non c'è bisogno di inventare nulla. Tutto dipende dalla situazione. Qual è l'obiettivo? Se due numeri possono differire in mantissa 0,1, e se è CRITICO, è una cosa, se non è importante, è un'altra. Dipende da cosa si sta paragonando l'uno con l'altro. Ma la FLESSIBILITÀ, data da un compilatore VERO senza fronzoli, è una cosa VERA e necessaria, IMHO.

:)

 
SK. писал (а):
Il problema qui non è la precisione del codice del programma, ma le caratteristiche tecnologiche dei calcoli e le regole tecnologiche per la memorizzazione dei valori delle variabili. Se non fosse stato per questo, la domanda non sarebbe nemmeno sorta.
È vero per quanto riguarda i calcoli, ma mi è sembrato che tutto debba essere migliore con lo stoccaggio. E quando le cifre = 4, la differenza della quindicesima cifra non dovrebbe giocare un ruolo.
 
Depfy:

Perbacco, credo di cominciare a capire il perché di tutto questo trambusto...

In generale, non credo che ci sia NULLA da inventare. Perché tutto dipende dalla situazione. Qual è l'obiettivo? Se due numeri possono differire in mantissa 0,1, e se è CRITICO, è una cosa, se non è importante, è un'altra. Dipende da cosa si sta paragonando l'uno con l'altro. Ma la FLESSIBILITÀ, data da un compilatore VERO senza fronzoli, è una cosa VERA e necessaria, IMHO.

:)


Non posso rispondere sul fatto di "inventare". A quanto pare, dipende da cosa stai pensando:)

Per esempio, invenzioni come Point/2 permettono davvero di fare dei calcoli con una certa precisione in alcuni casi. Tuttavia, è meglio usare la raccomandazione degli sviluppatori, cioè prendere come regola, una volta per tutte (fino alla nuova documentazione), di usare la funzione NormalizeDouble() quando si calcolano operazioni di confronto.

 
lna01:
SK. ha scritto (a):
Il problema qui non è la precisione del codice del programma, ma le caratteristiche tecnologiche dei calcoli e le regole tecnologiche per la memorizzazione dei valori delle variabili. Se non fosse stato per questo, la domanda non sarebbe nemmeno sorta.
Questo è vero per i calcoli, ma ho pensato che dovrebbe essere meglio per la conservazione. E con cifre = 4, la differenza nella quindicesima cifra non dovrebbe avere importanza.

E non importa se usate NormalizeDouble(). E se non lo usi, è una questione di fortuna.