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

 
SK. писал (а):
VBAG:
Non me lo aspetterei da te.

Mi rimangio tutto.
Sono contento di essermi sbagliato nei miei dubbi.
 

A SK.

Lo sai meglio tu. Non considero MQL un linguaggio di programmazione. È proprio un DIALETTO.

A proposito, due cose mi danno la nausea:

1) nessuna enumerazione di operazioni, cioè parentesi graffe

2) ritorno - sei terribilmente stanco delle parentesi.

Tutto sommato, ben fatto ragazzi.

Kernighan e Ritchie - un applauso per loro.

 
VBAG писал (а):
Mi rimangio quello che ho detto.
Sono contento di essermi sbagliato nei miei dubbi.


Non abbiamo avuto una discussione :)

Depfy:

Non considero MQL un linguaggio di programmazione. È proprio un DIALETTO.

Probabilmente è una questione di terminologia. Io, per esempio, trovo in MQL tutti gli attributi di un linguaggio completo. In ogni caso, è uno dei pochi linguaggi (notevolmente, il migliore) che permette ai commercianti di meccanizzare e automatizzare le loro attività. Penso che questo linguaggio sia abbastanza soddisfacente almeno nel senso che le sue possibilità molte volte superano le esigenze della maggior parte degli algoritmi (in altre parole - se ci fossero abbastanza idee ben pensate, e i mezzi per la loro attuazione sono già disponibili).
 
SK. писал (а):
...

Così com'è, il valore iniziale della variabile 123.00000000000 può risultare essere 122.99999999999999 quando viene usato nei calcoli. E questo nonostante il fatto che da quando la variabile è stata scoperta, il suo valore non è mai cambiato, ma è stato solo richiesto dal programma per partecipare ad altri calcoli.


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

Sei sicuro di quello che dici? Se può specificare la fonte della sua conoscenza?

Allora ho questa domanda per te

1? se il problema è ricordare o leggere una variabile, come può NormalizeDouble() aiutare se anche il valore di ritorno viene ricordato o letto con un errore?
2. Perché lo schema NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits), dove !OC! - operatore di confronto, non funziona sempre? anche se è inserito direttamente in if?
3? Sapete come funziona NormalizeDouble() (algoritmo della funzione)?
4? Ho scritto la mia opinione su questo, cosa ne pensi?

gravity001 ha scritto (a):

...
Vi ho già parlato della normalizzazione. Prima dimmi perché hai bisogno di applicarlo e poi come e dove.

Questa è la domanda chiave, vero? Anch'io ci ho pensato a lungo: "si inserisce il doppio e si ottiene il doppio ", cosa potrebbe cambiare?
Non ho trovato la risposta esatta. Ma immagino che sia così

doppio a = 2.000000000000
doppio b = 2.000000000001
doppio c = 1.99999999999999

Tutte queste variabili sono diverse e sono memorizzate con precisione fino all'ultima cifra!
In questo caso, siamo noi stessi a definire i segni (cifre). Tutto ciò che non è definito è riempito di zeri.

Se avessimo definito il doppio a = 2,0, ed esso è memorizzato come 2,0000001 o 1,9999999, è chiaro che NormalizeDouble() non sarebbe di aiuto, perché restituirebbe un valore impreciso!
Penso che un tale errore non si verifichi quasi mai quando si memorizza un valore di variabile. Inoltre, non credo che il numero 2.0 sia memorizzato come 1.99999999999999999 di proposito, poiché ogni carattere (cifra o punto) è memorizzato con un bit specifico nella stringa di bit! Pertanto, il numero 2.0 è memorizzato in modo sicuro come 2.00000...00.

L'altro caso è quando non siamo noi stessi a determinare i segni:

a = 4.0;
b = 2.0;
c = a / b // - l'operazione di "divisione" è fatta dal processore, o meglio dal co-processore, e riempie il premenente di caratteri (cifre).

Dopo l'operazione può essere:
Più comunemente:
с = 2.000...0
с= 1.99999999...
с= 2.00000001...

cioè il risultato spesso differisce dal valore vero di una piccola quantità.

I grandi errori si verificano molto raramente:
с = 2.3

Qui ci sono due spiegazioni:
1) una parte della stringa di bit è stata influenzata in memoria quando si chiama a o b, cioè le variabili a e b sono state cambiate.
2) si è verificato un errore durante l'operazione "divide".

Penso che il 2) si verifichi più spesso. Perché non lo so. Penso che abbia a che fare con il fatto che il co-processore è destinato ad essere altamente ottimizzato a scapito dell'inutilità.

Quando si confronta una variabile con il numero 2.000...00, l'uguaglianza ovviamente fallisce. Non tutti i bit saranno uguali.

Ora, NormalizeDouble() è qui per aiutare!
NormalizeDouble() "aggiusterà" questo piccolo errore!
Poiché l'errore è spesso molto piccolo, l'arrotondamento con una piccola precisione darà sempre il risultato corretto.

Guardatela in questo modo:
Arrotondare il numero a = 2,111...11 alla seconda cifra.
NormalizeDouble() scriverà 2.11 in una nuova variabile e riempirà i bit rimanenti con zeri, non con uno!
Penso che sarà così:

double MyNormalizeDouble(double value, int digits)
{
     int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                       с помощью которого мы из VALUE сделаем целое число
     double result = MathRound(factor * value) / factor;
     return(result);
}
Qui, ho fatto del mio meglio per spiegare perché NormalizeDouble() è necessaria.

Fino a poco tempo fa ero completamente soddisfatto di questa spiegazione, ma recentemente mi sono convinto che questo schema non funziona sempre

NormalizeDouble(a, 2) ! NormalizeDouble(b, 2) dove !OC! - è un operatore di confronto.
Anche se secondo la mia comprensione deve sempre funzionare!
Pertanto, sarò lieto di ricevere qualsiasi critica ragionata e comprensibile!
 
gravity001:
SK. ha scritto (a):
...

Così com'è, il valore iniziale della variabile 123.00000000000 può risultare essere 122.99999999999999 quando viene usato nei calcoli. E questo nonostante il fatto che da quando la variabile è stata scoperta, il suo valore non è mai cambiato, ma è stato solo richiesto dal programma per partecipare ad altri calcoli.

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

Sei sicuro di quello che dici? Potrebbe indicare la fonte della sua conoscenza?
Sono sicuro. La fonte della vostra conoscenza è la vostra esperienza nella programmazione MQL4 e le consultazioni degli sviluppatori.
1. Se il problema è nel ricordare o leggere una variabile, come può aiutare NormalizeDouble(), se anche il valore di ritorno viene ricordato o letto con un errore?
NormalizeDouble() dovrebbe essere applicato immediatamente prima dell'operazione di confronto. Il risultato dell'operazione di confronto è un valore di tipo booleano, che non è mai "corrotto".
2. Perché lo schema NormalizeDouble(value, digits) ! NormalizeDouble(value, digits) , dove !OC! è l'operatore di confronto, non funziona sempre? Anche se lo inserite direttamente in if?
Non ho detto questo. È esattamente così che funziona ed è quello che dovreste fare.
3? Sapete come funziona NormalizeDouble() (algoritmo di funzione)?
No, non lo so. Si prega di riferirlo agli sviluppatori.
4. Ho scritto la mia opinione su questo argomento, cosa ne pensi?
La tua opinione è interessante, ma questa domanda è stata risolta da tempo. È meglio usare le raccomandazioni degli sviluppatori e non reinventare la ruota.
 
SK. писал (а):
gravità001:

2. Perché lo schema NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , dove !OC! è un operatore di confronto, non funziona sempre, anche se lo inserite direttamente in if?
Non ho detto questo. È esattamente così che funziona ed è così che si dovrebbe fare.

Qui ci sono altre opinioni su questo argomento

'Ancora sul confronto di due doppi', 1 pagina dal primissimo post!

Integro 24.12.2006 15:23

Sfortunatamente, la costruzione NormalizeDouble(x-y,Digits) non è identica alla costruzione NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits)

Renat 24.12.2006 16:15

E non dovrebbe essere identico. La prima è corretta.

Penso che il costrutto sia
se (NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
e la costruzione
se (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sono identici!

Cosa ne pensate?
 
gravity001:

Renat 24.12.2006 16:15

E non deve essere identico. Il primo è corretto.

Penso che la costruzione
se(NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
e la costruzione
se (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sono identici!

Cosa ne pensate?


E l'opinione di Renat non è interessante? Non vi interessa l'opinione dell'amministratore delegato della società che sviluppa la MT?

O sei come la vecchia della fiaba di Pushkin? Basta volere-volere-volere! Ricorda come finisce la storia. "Il pesce non disse nulla, scosse la coda e nuotò via verso il mare blu. Ha aspettato a lungo in riva al mare per una risposta. Non ha aspettato, si è voltato verso la vecchia..."

 
SK. писал (а):
Ilprimo è gravity001:


Renat 24.12.2006 16:15

E non deve essere identico. La prima è corretta.

Penso che la costruzione
se(NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
e la costruzione
se (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sono identici!

Cosa ne pensate?



E l'opinione di Renat non è interessante? Non vi interessa l'opinione dell'amministratore delegato della società che sviluppa la MT?


O sei come la vecchia della fiaba di Pushkin? Basta volere-volere-volere! Ricorda come finisce la storia. "Il pesce non disse nulla, scosse la coda e nuotò via verso il mare blu. Ha aspettato a lungo in riva al mare una risposta. Non ha aspettato, si è voltato verso la vecchia..."



Beh, Renat ha detto che il primo modo è giusto e il secondo è sbagliato, e tu hai detto che il secondo modo è giusto, giusto?

2. Perché lo schema NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , dove !OC! è un operatore di confronto, non funziona sempre, anche se lo inserite direttamente in if?
Non ho detto questo. È esattamente così che funziona, ed è così che dovrebbe essere fatto.
 

L'ho detto nel senso di un paragone più o meno importante:

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))

il che significa che le costruzioni del tipo non sempre funzionano:

double a = NormalizeDouble(x,Digits);
double b = NormalizeDouble(y,Digits);
 
if (a > b)
  {
  ...
  }

cioè NormalizeDouble() dovrebbe essere inserita proprio nell'intestazione dell'operatore, il più vicino possibile a dove viene calcolata l'operazione di confronto.

Per quanto riguarda l'opinione degli sviluppatori, non intendo contestarla.

E poi... quel thread trattava un costrutto completamente diverso:

 
SK. писал (а):

L'ho detto sottintendendo un paragone più o meno importante:

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))
Non ho controllato il più o il meno, ma ho controllato l'uguaglianza.
Ho avuto errori di confronto quando ho usato questa costruzione:

if (NormalizeDouble(x, digits) == NormalizeDouble(y, digits))
{
    ...
}
Perché, non lo sai?
Motivazione: