Frage an die MQL4-Meister. Nochmals zu Double Compare. - Seite 5

 

Erstaunliche Schlussfolgerung! Wie kommen Sie auf die Idee, dass es sich um eine beliebige Ziffer handelt, wenn Sie nicht einmal "verstehen", was eine Ziffer überhaupt ist?

 
Integer:

Erstaunliche Schlussfolgerung! Wie kommen Sie auf die Idee, dass es sich um eine beliebige Ziffer handelt, wenn Sie nicht einmal "verstehen", was eine Ziffer überhaupt ist?

Fängst du an, auf Wörtern herumzuhacken? Es ist offensichtlich, dass es sich um einen Anschlag auf die Persönlichkeit handelt. :)
Ich möchte gleich sagen, dass ich es vorziehe, mich nicht an solchen Erklärungen zu beteiligen, denn wenn man in der Sache nichts zu sagen hat, warum sollte man dann überhaupt reden?
 
VBAG:
Ich möchte mich bei allen Profis für ihre Einsichten bedanken!

Irtron, ich habe mich für deine Variante entschieden, sie hat mir sehr gut gefallen. Ich habe sie für allgemeine Fälle ein wenig korrigiert und überprüft:

int ComparePrice(double a, double b, double digit)
{
a -= b;
b = Ziffer;
wenn (a > b)
zurück (1);
wenn (a < -b)
zurück (-1);
zurück (0);
}
Danke.
Ich habe vergessen klarzustellen, dass ich einen beliebigen vordefinierten Wert in digit übergeben möchte:
double digit14=0.00000000000001;
Doppelte Ziffer12=0,000000000001;
double digit8=0,00000001;
doppelte Ziffer4=0,0001;
double digit2=0,01;
die die erforderliche Genauigkeit bestimmen wird.
Für diese Funktion arbeitet sie sehr schnell.
Irtron, ich danke Ihnen nochmals.

 
Irtron:
Ganzzahlig:

Erstaunliche Schlussfolgerung! Wie kommen Sie auf die Idee, dass es sich um eine beliebige Ziffer handelt, wenn Sie nicht einmal "verstehen", was eine Ziffer überhaupt ist?

Fängst du an, auf Wörtern herumzuhacken? Natürlich wird es von nun an persönlich werden. :)
Ich möchte gleich sagen, dass ich es vorziehe, mich nicht an solchen Erklärungen zu beteiligen, denn wenn man in der Sache nichts zu sagen hat, warum sollte man dann überhaupt reden?


Ich habe gerade gelesen, was Sie geschrieben haben. Ihr Verständnis ist offensichtlich durch "Ihre eklatante..." beeinträchtigt. (Sie nennen das Wort)"

VBAG, warum das Rad neu erfinden, wenn es eine Funktion NormalizeDouble() gibt, die zwei Zahlen schneller vergleicht als ComparePrice()?

 
Integer:

VBAG, warum das Rad neu erfinden, wenn es eine NormalizeDouble() Funktion gibt, die zwei Zahlen schneller vergleicht als ComparePrice()?

Die Funktion vergleicht zwei Double-Zahlen und gibt die Antwort <, > oder = mit 14 Dezimalstellen. (NormalizeDouble() ist auf 8 Stellen begrenzt)
Wenn Sie ein ähnliches Fahrrad oder bessere Alternativlösungen vorschlagen können, würde ich sie gerne verwenden.
Hochachtungsvoll,
Wladimir
 
VBAG:
Ganzzahlig:

VBAG, warum das Rad neu erfinden, wenn es eine NormalizeDouble() Funktion gibt, die zwei Zahlen schneller vergleicht als ComparePrice()?

Die Funktion vergleicht zwei Double-Zahlen und gibt die Antwort <, > oder = mit 14 Dezimalstellen. (NormalizeDouble() ist auf 8 Stellen begrenzt)
Wenn Sie ein ähnliches Rad oder bessere Alternativen vorschlagen können, würde ich sie gerne verwenden.
Hochachtungsvoll,
Wladimir
Hier ist ein Test für mein 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

Schlussfolgerung:
Die CD-Funktion vergleicht zwei Double-Zahlen, gibt die Antwort <, > oder = mit 14 Dezimalstellen und arbeitet 2 mal schneller als die einfache Durchführung von NormalizeDouble() (auch ohne Logik zum Vergleich).
 
Ja, zwei Aufrufe von NormalizeDouble() dauern länger als CD, und ein Aufruf ist schneller. Die Genauigkeit von 14 Ziffern ist eine schöne Sache :-)
 
Ich habe in letzter Zeit auch versucht, echte Zahlen zu vergleichen!

Viele Leute schreiben, dass zum Vergleichen die eingebaute Funktion NormalizeDouble() verwendet werden muss. (dies wird auch von den Entwicklern empfohlen).
Daher möchte ich zunächst eine Definition geben: "Was ist NormalizeDouble()?", d.h. wie funktioniert es, was ist sein Algorithmus.

MQL4 Referenz - Datenkonvertierungen - NormalizeDouble

Rundung einer Fließkommazahl auf eine bestimmte Genauigkeit.
...

Ich weiß nicht, wie die Rundung in MQL4 organisiert ist (fragen Sie die Entwickler), aber ich kenne eine Standardmethode, die Fließkommazahlen auf eine bestimmte Genauigkeit rundet:
Hier, eine Funktion:

double MyNormalizeDouble(double value, int digits)
{
    int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                      с помощью которого мы из VALUE сделаем целое число
    double result = MathRound(factor * value) / factor;
    
    return(result);
}
Aus dieser Funktion können Sie ersehen, dass wir zuerst von einer reellen Zahl zu einer ganzen Zahl und dann wieder zurück zu einer reellen Zahl gehen.
Zum Vergleich genügt es, nur eine ganze Zahl zu verwenden.

Daher bin ich der Meinung, dass der schnellste und zuverlässigste Weg, reelle Zahlen zu vergleichen, darin besteht, sie in ganze Zahlen umzuwandeln.
So sieht der Vergleich aus:

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
}

All dies kann in einer Funktion formatiert und verwendet werden. Es ist mühsam zu schreiben, es scheint klar zu sein, wie man eine Funktion macht!
Ich denke, dieser Weg ist schneller als der Aufruf von NormalizeDouble().

Um sicher zu gehen, können Sie auch die Funktion MathRound() dazu bringen, eine ganze Zahl zurückzugeben, da sie standardmäßig double zurückgibt.
Am einfachsten geht es auf diese Weise

int MyMathRound(double value)
{
    int result = MathRound(value);
    return(result);
}
Dann werden nur ganze Zahlen verglichen, und die sind gut vergleichbar!


Ich denke, dieser Weg ist am besten geeignet, oder?
 
gravity001:

Der schnellste und zuverlässigste Weg ist, die reellen Zahlen in ganze Zahlen umzuwandeln
Der Vergleich würde folgendermaßen aussehen:

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
}

Ich denke, das ist der richtige Weg, oder nicht?

Das glaube ich nicht. Urteilen Sie selbst:
Die ganze Schönheit des Irtron-Codes liegt in seiner Kompaktheit (absolut nichts extra - sogar Variablen werden gespeichert!).
Und Sie schlagen vor, dass wir mindestens zwei weitere Operationen für jede
(а - b)
Operation hinzufügen sollten.
(MathRound( (а - b) * factor ) 
Das ist ein Geschwindigkeitsvorteil!
 
VBAG:
Das glaube ich nicht. Urteilen Sie selbst

Ja, ein bisschen langsamer:
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