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

 

Conclusione sorprendente! Cosa ti fa pensare che con qualsiasi cifra, se non hai nemmeno "capito" cos'è una cifra?

 
Integer:

Conclusione sorprendente! Cosa ti fa pensare che con qualsiasi cifra, se non hai nemmeno "capito" cos'è una cifra?

Cominci a prendertela con le parole? Ovviamente, questo sarà un assassinio della personalità. :)
Devo dire subito che preferisco non partecipare a queste spiegazioni, perché se non si ha niente da dire nel merito, perché parlare?
 
VBAG:
Vorrei ringraziare tutti i professionisti per le loro intuizioni!

Irtron, ho scelto la tua variante, mi è piaciuta molto. L'ho corretto un po' per i casi generali e l'ho controllato:

int ComparePrice(double a, double b, double digit)
{
a -= b;
b = cifra;
se (a > b)
ritorno (1);
se (a < -b)
ritorno (-1);
ritorno (0);
}
Grazie.
Ho dimenticato di chiarire che voglio passare qualsiasi valore predefinito nella cifra:
double digit14=0.00000000000001;
doppia cifra12=0.000000000001;
doppia cifra8=0,00000001;
doppia cifra4=0,0001;
doppia cifra2=0,01;
che determinerà la precisione richiesta.
Per questa funzionalità, funziona molto rapidamente.
Irtron, grazie ancora.

 
Irtron:
Intero:

Conclusione sorprendente! Cosa ti fa pensare che con qualsiasi cifra, se non hai nemmeno "capito" cos'è la cifra?

Comincia a prendersela con le parole? Ovviamente, il prossimo passo sarà un assassinio della personalità. :)
Devo dire subito che preferisco non partecipare a queste spiegazioni, perché se non si ha niente da dire nel merito, perché parlare?


Perché prendersela, ho appena letto quello che hai scritto. La tua comprensione è ovviamente ostacolata dalla "tua palese... (tu nominare la parola)".

VBAG, perché reinventare la ruota quando c'è una funzione NormalizeDouble() che confronta due numeri più velocemente di ComparePrice()?

 
Integer:

VBAG, perché reinventare la ruota quando c'è una funzione NormalizeDouble() che confronta due numeri più velocemente di ComparePrice()?

La funzione confronta due numeri doppi e dà la risposta <, > o = con 14 cifre decimali (NormalizeDouble() è limitata a 8 cifre)
Se puoi suggerire una moto simile o soluzioni alternative migliori, sarei felice di usarle.
Con rispetto,
Vladimir
 
VBAG:
Intero:

VBAG, perché reinventare la ruota quando c'è una funzione NormalizeDouble() che confronta due numeri più velocemente di ComparePrice()?

La funzione confronta due numeri doppi e dà la risposta <, > o = con 14 cifre decimali (NormalizeDouble() è limitata a 8 cifre).
Se puoi suggerire una ruota simile o alternative migliori, sarei felice di usarle.
Con rispetto,
Vladimir
Ecco un test per il mio interesse:
int start()
  {
//----
    double a = 1.23450001, b = 1.23449999;
 
    int start1 = GetTickCount(), c1;
    for ( c1 = 0; c1 < 100000000; c1 ++ ) CD( a, b,0.00000001);
    int end1 = GetTickCount();
    
 
    int start2 = GetTickCount(), c2;
    for ( c2 = 0; c2 < 100000000; c2 ++ )   xNormalize(a,b,8);
    int end2 = GetTickCount();
 
    Print( "CD: ", (end1-start1), ", xNormalize: ", (end2-start2) );
 
    return(0);
   }
 
//+ CompareDouble ---------------------------------------------------+ CompareDouble
int CD(double a, double b, double digit)
{
    a -= b;
    b = digit;
    if (a > b)
        return (1);
    if (a < -b)
        return (-1);
    return (0);
}
 
// Две операции NormalizeDouble----
bool xNormalize(double a, double b,int digit)
  {
   double d1 = NormalizeDouble(a,digit);
   double d2 = NormalizeDouble(b,digit);
   
//   bool bCompare=d2-d1 > 0.0;
   bool bCompare= 0;
   return(bCompare);
2007.09.12 07:15:09 $CheckCompareDouble USDJPY,M5: CD: 20485, xNormalize: 51265

Conclusione:
La funzione CD confronta due numeri doppi, dà la risposta <, > o = con 14 cifre decimali e funziona 2 volte più velocemente che eseguire semplicemente NormalizeDouble() (anche senza logica per confrontarli).
 
Sì, due chiamate a NormalizeDouble() richiedono più tempo di CD, e una chiamata è più veloce. La precisione di 14 cifre è un bel tocco :-)
 
Anche io ho cercato di confrontare i numeri reali di recente!

Molte persone scrivono che per confrontare devono usare la funzione integrata NormalizeDouble(). (questo è quello che raccomandano anche gli sviluppatori).
Pertanto, vorrei prima definire: "cos'è NormalizeDouble()?", cioè come funziona, qual è il suo algoritmo.

Riferimento MQL4 - Conversioni di dati - NormalizeDouble

Arrotondamento di un numero in virgola mobile ad una precisione specificata.
...

Non so come sia organizzato l'arrotondamento in MQL4 (chiedete agli sviluppatori), ma conosco un metodo standard che arrotonda i numeri in virgola mobile alla precisione specificata:
Qui, una funzione:

double MyNormalizeDouble(double value, int digits)
{
    int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                      с помощью которого мы из VALUE сделаем целое число
    double result = MathRound(factor * value) / factor;
    
    return(result);
}
Da questa funzione si può vedere che si passa prima da un numero reale a un intero, e poi di nuovo a un numero reale.
Per il confronto, è sufficiente andare a un solo intero.

Pertanto, credo che il modo più veloce e affidabile per confrontare i numeri reali sia quello di convertirli in numeri interi.
Ecco come sarà il confronto:

double a;
double b;
int factor = MathRound( MathPow(10, digits) ); // digits - это точность с которой будем сравнивать
                                                           Если сравниваем цены, то это предопределенная переменная Digits
...

if (MathRound( (а - b) * factor )  !=  0)
{
    ... // a != b
}

if (MathRound( (а - b) * factor )  ==  0)
{
    ... // a == b
}

if (MathRound( (а - b) * factor )  >  0)
{
    ... // a > b
}

if (MathRound( (а - b) * factor )  <  0)
{
    ... // a < b
}

Tutto questo può essere formattato in una funzione e utilizzato. È una sofferenza scrivere, sembra essere chiaro come fare una funzione!
Penso che questo modo sia più veloce che chiamare NormalizeDouble().

Per essere sicuri, potete anche fare in modo che la funzione MathRound() restituisca un intero, dato che per default restituisce il doppio.
Il modo più semplice per farlo è questo

int MyMathRound(double value)
{
    int result = MathRound(value);
    return(result);
}
Allora solo i numeri interi saranno confrontati, e si confrontano bene!


Penso che questo modo sia il più corretto, no?
 
gravity001:

Quindi penso che il modo più veloce e affidabile sia quello di convertire i numeri reali in interi
Il confronto sarebbe così:

double a;
double b;
int factor = MathRound( MathPow(10, digits) ); // digits - это точность с которой будем сравнивать
                                                           Если сравниваем цены, то это предопределенная переменная Digits
...

if (MathRound( (а - b) * factor )  !=  0)
{
    ... // a != b
}

if (MathRound( (а - b) * factor )  ==  0)
{
    ... // a == b
}

if (MathRound( (а - b) * factor )  >  0)
{
    ... // a > b
}

if (MathRound( (а - b) * factor )  <  0)
{
    ... // a < b
}

Penso che questo sia il modo giusto per farlo, no?

Non credo. Giudicate voi stessi:
Tutta la bellezza del codice di Irtron è nella sua compattezza (assolutamente nulla di extra - anche le variabili sono salvate!).
E tu suggerisci di aggiungere altre due operazioni per ogni operazione
(а - b)
almeno.
(MathRound( (а - b) * factor ) 
Questo è un vantaggio in termini di velocità!
 
VBAG:
Non credo. Giudicate voi stessi

Sì, un po' più lento:
int start()
{
    double a, b;
    int start1, start2, end, c;
    
    a = 1.23450001;
    b = 1.23449999;
    
    start1 = GetTickCount();
    
    for (c = 100000000; c > 0; c--)
        ComparePrice(a, b,0.0001);
    
    start2 = GetTickCount();
    
    for (c = 100000000; c > 0; c--)
        intCompare(a, b,10000);
    
    end = GetTickCount();
 
    Print("ComparePrice: ", start2 - start1, ", intCompare: ", end - start2);
 
    return(0);
}
 
int ComparePrice(double a, double b, double point)
{
    a -= b;
    b = point / 2.;
    if (a > b)
        return (1);
    if (a < -b)
        return (-1);
    return (0);
}
 
int intCompare(double a, double b, int factor)
{
    return(MathRound( (a-b) * factor ));
}
ComparePrice: 32032, intCompare: 35296
Motivazione: