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

 
Hallo!
Wie Sie wissen, hängt nicht nur die Korrektheit der Berechnungen, sondern auch die Zuverlässigkeit des geschriebenen Codes vom Programmierstil und der Sauberkeit des Codes ab.
Wir schreiben kein Spielzeug, daher ist die Zuverlässigkeit des geschriebenen Programms die allererste Voraussetzung. Die meisten Berechnungen werden in Dubles durchgeführt und ein korrekter Vergleich im Code von
von zwei reellen Zahlen im Programmcode erfordert eine bestimmte Vorgehensweise und Genauigkeit.
Ich versuche, den "richtigen" Programmierstil herauszufinden, daher die Frage:

Für einen Ausdruck

Doppel-A;
doppeltes b;

if(a==b) oder if(a!=b)
{......} {......}

Die Entwickler empfehlen dies
//+------------------------------------------------------------------+
//| Vergleichsfunktion zweier reeller Zahlen.
//+------------------------------------------------------------------+
bool CompareDouble(double Zahl1, double Zahl2)
{
bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
return(Compare);
}
//+------------------------------------------------------------------+


Ist dieser Code korrekt?

Doppel-A;
doppeltes b;

if(a>b) if(a<b)
{......} {......}


Höchstwahrscheinlich nicht im allgemeinen Fall. Wie kann man das richtig überprüfen?
Welche Art der Arbeit mit Dubles ist im Allgemeinen besser geeignet?
Vielen Dank im Voraus an alle, die uns antworten.
 

Ich ziehe es vor, wenn möglich die größeren und kleineren Ziffern zum Vergleich heranzuziehen,

double a;
double b;
 
if(a>b)             if(a<b)
    {......}            {......}

damit ich mir nicht zu viele Gedanken darüber machen muss, ob ich bis zu einer bestimmten Zahl doppelt so viel laufen muss

Vol = 156.00000002; 
NormVol = NormalizeDouble(Vol,2); 
156.00

Wenn es notwendig ist, die Zahlen zusammenzustellen

if(a==b)    или         if(a!=b)
    {......}                    {......}

dann konvertiere ich zunächst beide Zahlen in eine einzelne Ziffer nach dem Punkt

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......}
 
xeon:

Ich konvertiere zunächst beide Zahlen in dieselbe Ziffer nach dem Punkt

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
Und bei der Berechnung in Indikatoren verwenden Sie Normalize und ähnliche Präparate?
Ich schaue mir eine Menge Code an, ich lerne gerade zu programmieren, und es ist selten im Indikatorcode zu finden. Das ist die Frage - wie man es richtig macht.
 
VBAG:
xeon:

Ich konvertiere zunächst beide Zahlen in dieselbe Ziffer nach dem Punkt

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
Verwenden Sie Normalize und ähnliche Präparate in Ihren Indikatorberechnungen?
Ich schaue mir eine Menge Code an, ich lerne gerade zu programmieren, und es ist selten im Indikatorcode zu finden. Das ist die Frage - wie man es richtig macht.

Ich versuche es zu vermeiden,NormalizeDouble oder "<" und ">" Zeichen zu verwenden, weil der Indikator, das Skript oder der Expert Advisor Diskrepanzen im Double haben kann.
 
xeon ,
Ich danke Ihnen für Ihre Meinung.
 
Normalisieren Sie immer und es wird nie ein Problem mit Dubs geben! ;)
In jedem Vergleich, in jedem Dilemma, und mit einer bewusst gewählten Genauigkeit.

//--- NormalizeDouble
double nd( double value, int precision )
{
    return( NormalizeDouble( value, precision ) );
}
 
//--- MathAbs
double abs( double value )
{
    return( MathAbs( value ) );
}
 
//--- Если value1 равняется value2 до precision знака после запятой, возвращает true, иначе - false.
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( nd( value1, precision ) - nd( value2, precision ) ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}

Achten Sie auf die Gleichheitsfunktion - wenn auch leicht verändert:
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( value1 - value2 ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}
(Entfernen Sie die Normalisierung jeder Zahl vor dem Vergleich), so ergibt sich ein anderes Ergebnis.

Zum Beispiel wird equal( 0.123456784, 0.123456776 ) im ersten Fall true zurückgeben, im zweiten Fall false;)
 
komposter:
Normalisieren Sie immer und es wird nie ein Problem mit Dubs geben! ;)
Aber es wird Leistungsprobleme geben. Das Problem des Vergleichs von Zahlen mit doppelter Genauigkeit ist weit hergeholt und beruht auf grundlegender Unkenntnis der Mathematik.
 
Irtron:
Das Problem des Vergleichs von Zahlen mit doppelter Genauigkeit ist weit hergeholt und beruht auf grundlegender Unkenntnis der Mathematik.

Lassen Sie mich das erklären.

Offensichtlich gibt es eine Verwechslung der Begriffe. In der Intel-Architektur wird ein Gleitkomma-Zahlentyp verwendet, um Zahlen mit fester Genauigkeit darzustellen, zu denen insbesondere alle Werte des Handelsumfelds gehören, da der Prozessor über einen speziellen Drescher für die Gleitkomma-Arithmetik verfügt.

Tatsächlich unterscheiden sich Zahlen mit fester Genauigkeit in Bezug auf die maschinelle Darstellung nur wenig von ganzen Zahlen. Das Vorhandensein einer Dezimalstelle ist in diesem Fall bedingt. Diese Eigenschaft wird häufig in Architekturen verwendet, bei denen die Fließkomma-Arithmetik nicht von der Hardware unterstützt wird, wie z. B. bei ARM, das sich durch die Verwendung in PDAs und Smartphones verbreitet hat. Fließkomma-Arithmetik muss dort mit ziemlich schwerem Code emuliert werden, was den Prozessor erwärmt und somit die Batterie verschwendet, ganz zu schweigen von der Geschwindigkeit der Programmausführung. Wann immer es also nicht möglich ist, mit ganzen Zahlen zu arbeiten, wird ein festes Format verwendet, und in den extremsten Fällen wird eine Gleitkommazahl verwendet. Oder besser gesagt, natürlich sollte es so sein.

Nichts spricht gegen die Verwendung fester (d.h. ganzzahliger) Arithmetik für Marktwerte.

Dies gilt nicht für die berechneten Werte der Indikatoren. Ein direkter Vergleich ist da völlig ausreichend. Warum sollte man sie mit Genauigkeit vergleichen?
 
Danke an Komposter und Irtron! Ich habe bereits beschlossen, dass nichts mehr geschrieben wird, und habe mich hingesetzt, um mich zu erfinden, und habe Ihre Beiträge nicht gesehen.
Bitte sehen Sie sich an, was ich mit meiner eigenen schlauen Hand geschrieben habe:
//+------------------------------------------------------------------+
bool EqualDouble(double dN1, double dN2,int Digit)
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 == 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool LessDouble(double dN1, double dN2,int Digit) // Wenn dN1<dN2
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d2-d1 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool MoreDouble(double dN1, double dN2,int Digit) // Wenn dN1>dN2
{
double d1 = NormalizeDouble(dN2,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
Покритикуйте, пожалуйста.
 
VBAG:
Bitte sehen Sie, was ich mit meiner schlampigen Hand gekritzelt habe:
Welche Werte versuchen Sie zu vergleichen? Preise, Lose oder Indikatorwerte?
 
Irtron:
VBAG:
Bitte sehen Sie sich an, was ich mit meiner schlampigen Hand gekritzelt habe:
Welche Werte versuchen Sie zu vergleichen? Preise, Partien oder Indikatorwerte?
Ich habe am Anfang geschrieben: "Ich versuche, den 'richtigen' Programmierstil zu finden. "
Im Grunde genommen macht es keinen Unterschied, was in den Dubles steht - nur die Genauigkeit der Digit-Rundung variiert, je nach den Anforderungen der Variablen.