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

 
SK. писал (а):
VBAG:
Das würde ich von Ihnen nicht erwarten.

Ich nehme es zurück.
Ich bin froh, dass ich mit meinen Zweifeln falsch lag.
 

TO SK.

Sie wissen es am besten. Ich halte MQL nicht für eine Programmiersprache. Es ist einfach so ein DIALECT.

Übrigens stören mich zwei Dinge darin:

1) keine Aufzählung von Operationen, d.h. geschweifte Klammern

2) return - Sie sind der Klammern überdrüssig.

Alles in allem, gut gemacht, Jungs.

Kernighan und Ritchie - ein Applaus für sie.

 
VBAG писал (а):
Ich nehme das zurück.
Ich bin froh, dass ich mit meinen Zweifeln falsch lag.


Wir haben uns nicht gestritten :)

Depfy:

Ich betrachte MQL nicht als eine Programmiersprache. Es ist einfach so ein DIALECT.

Es ist wahrscheinlich eine Frage der Terminologie. Ich zum Beispiel finde in MQL alle Attribute einer vollständigen Sprache. Auf jeden Fall ist es eine der wenigen Sprachen (und zwar die beste), die es den Händlern ermöglichen, ihre Aktivitäten zu mechanisieren und zu automatisieren. Ich denke, dass diese Sprache zumindest in dem Sinne zufriedenstellend ist, dass ihre Möglichkeiten die Bedürfnisse der meisten Algorithmen um ein Vielfaches übersteigen (mit anderen Worten - wenn es genügend gut durchdachte Ideen gäbe und die Mittel für ihre Umsetzung bereits vorhanden wären).
 
SK. писал (а):
...

So wie es aussieht, kann sich der Anfangswert der Variablen 123,00000000000 bei der Verwendung in den Berechnungen als 122,99999999999999 herausstellen. Und das, obwohl sich der Wert der Variablen seit ihrer Entdeckung nie geändert hat, sondern sie nur vom Programm angefordert wurde, um an anderen Berechnungen teilzunehmen.


Das ist der eigentliche Grund für die ganze Aufregung. Deshalb haben wir beschlossen, NormalizeDouble() so nah wie möglich an der eigentlichen Berechnung zu verwenden, vorzugsweise direkt in der Bedingung der if-, for- und while-Anweisungen.

Sind Sie sicher, was Sie sagen? Wenn Sie die Quelle Ihres Wissens angeben können?

Dann habe ich folgende Frage an Sie

1? Wenn das Problem das Speichern oder Lesen einer Variablen ist, wie kann NormalizeDouble() helfen, wenn der Rückgabewert ebenfalls mit einem Fehler gespeichert oder gelesen wird?
2? warum das Schema NormalizeDouble(value, digits) !OC! NormalizeDouble(Wert, Ziffern), wobei !OC! - Vergleichsoperator, funktioniert er nicht immer? auch wenn er direkt in if eingefügt wird?
3? Wissen Sie, wie NormalizeDouble() funktioniert (Funktionsalgorithmus)?
4? Ich habe meine Meinung dazu geschrieben, was meinen Sie?

gravity001 schrieb (a):

...
Ich habe Ihnen bereits von der Normalisierung erzählt. Sagen Sie mir zuerst, warum Sie es anwenden müssen, und dann wie und wo.

Das ist doch die entscheidende Frage, oder? Ich habe selbst lange darüber nachgedacht: "Du gibst das Doppelte ein und bekommst das Doppelte ". Was könnte sich denn ändern?
Ich habe die genaue Antwort nicht gefunden. Aber ich stelle mir das folgendermaßen vor

double a = 2.000000000000
double b = 2,000000000001
double c = 1,999999999999

Alle diese Variablen sind unterschiedlich und werden bis auf die letzte Stelle genau gespeichert!
In diesem Fall definieren wir die Zeichen (Ziffern) selbst. Alles, was nicht definiert ist, wird mit Nullen aufgefüllt.

Wenn wir double a = 2.0 definiert hätten, und es ist im Speicher als 2.0000001 oder 1.9999999 gespeichert, ist es klar, dass NormalizeDouble() nicht helfen würde, weil es einen ungenauen Wert zurückgeben würde!
Ich denke, ein solcher Fehler tritt fast nie auf, wenn man sich einen Variablenwert merkt. Außerdem glaube ich nicht, dass die Zahl 2,0 absichtlich als 1,999999999999999 gespeichert wird, da jedes Zeichen (Ziffer oder Punkt) mit einem bestimmten Bit in der Bitkette gespeichert wird! Daher wird die Zahl 2,0 sicher als 2,00000...00 gespeichert.

Der andere Fall ist, dass wir die Zeichen nicht selbst bestimmen:

a = 4.0;
b = 2.0;
c = a / b // - die "Divisions"-Operation wird vom Prozessor oder besser gesagt vom Koprozessor durchgeführt, der den Vorspann mit Zeichen (Ziffern) auffüllt.

Nach der Operation kann es sein:
Am häufigsten:
с = 2.000...0
с= 1.99999999...
с= 2.00000001...

d.h. das Ergebnis weicht oft um einen kleinen Betrag vom wahren Wert ab.

Große Fehler treten sehr selten auf:
с = 2.3

Hier gibt es zwei Erklärungen:
1) Beim Aufruf von a oder b wurde ein Teil der Bitfolge im Speicher beeinflusst, d.h. die Variablen a und b wurden verändert.
2) Bei der "Divide"-Operation ist ein Fehler aufgetreten.

Ich denke, dass 2) am häufigsten vorkommt. Warum ich das nicht weiß. Ich denke, es hat damit zu tun, dass der Co-Prozessor so stark optimiert werden soll, dass er unbrauchbar wird.

Wenn eine Variable mit der Zahl 2.000...00 verglichen wird, schlägt die Gleichheit offensichtlich fehl. Nicht alle Bits werden gleich sein.

Jetzt ist NormalizeDouble() da, um zu helfen!
NormalizeDouble() wird diesen kleinen Fehler "beheben"!
Da der Fehler oft sehr gering ist, führt eine Rundung mit geringer Genauigkeit immer zum richtigen Ergebnis.

Sehen Sie es einmal so:
Runden Sie die Zahl a = 2.111...11 auf die zweite Stelle.
NormalizeDouble() schreibt 2,11 in eine neue Variable und füllt die verbleibenden Bits mit Nullen auf, nicht mit Einsen!
Ich denke, es wird so aussehen:

double MyNormalizeDouble(double value, int digits)
{
     int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                       с помощью которого мы из VALUE сделаем целое число
     double result = MathRound(factor * value) / factor;
     return(result);
}
Hier habe ich versucht zu erklären, warum NormalizeDouble() benötigt wird.

Bis vor kurzem war ich mit dieser Erklärung völlig zufrieden, habe mich aber kürzlich davon überzeugen lassen, dass dieses Schema nicht immer funktioniert

NormalizeDouble(a, 2) ! NormalizeDouble(b, 2) wobei !OC! - ist ein Vergleichsoperator.
Obwohl es nach meinem Verständnis immer funktionieren muss!
Deshalb freue ich mich über jede begründete und verständliche Kritik!
 
gravity001:
SK. schrieb (a):
...

So wie es aussieht, kann sich der Anfangswert der Variablen 123,00000000000 bei der Verwendung in den Berechnungen als 122,99999999999999 herausstellen. Und das, obwohl sich der Wert der Variablen seit ihrer Entdeckung nie geändert hat, sondern sie nur vom Programm angefordert wurde, um an anderen Berechnungen teilzunehmen.

Das ist der eigentliche Grund für die ganze Aufregung. Deshalb musste ich NormalizeDouble() so nah wie möglich an der eigentlichen Berechnung einsetzen, am besten direkt in der Bedingung von if-, for-, while-Anweisungen.

Sind Sie sicher, was Sie sagen? Könnten Sie bitte die Quelle Ihres Wissens angeben?
Ich bin sicher. Die Quelle Ihres Wissens ist Ihre eigene Erfahrung in der MQL4-Programmierung und die Konsultation von Entwicklern.
Wenn das Problem im Speichern oder Lesen einer Variablen liegt, wie kann NormalizeDouble() helfen, wenn der Rückgabewert ebenfalls mit einem Fehler gespeichert oder gelesen wird?
NormalizeDouble() sollte unmittelbar vor der Vergleichsoperation angewendet werden. Das Ergebnis der Vergleichsoperation ist ein Wert vom Typ Boolean, der niemals "verfälscht" wird.
2? warum das Schema NormalizeDouble(value, digits) ! NormalizeDouble(value, digits) , wobei !OC! der Vergleichsoperator ist, funktioniert nicht immer, selbst wenn man ihn direkt in if? einfügt.
Das habe ich nicht gesagt. Genau so funktioniert es, und genau das sollten Sie auch tun.
3? Wissen Sie, wie NormalizeDouble() (Funktionsalgorithmus) funktioniert?
Nein, das tue ich nicht. Bitte wenden Sie sich an die Entwickler.
4 Ich habe meine Meinung zu diesem Thema geschrieben, was meinen Sie?
Ihre Meinung ist interessant, aber diese Frage ist schon lange geklärt. Es ist besser, die Empfehlungen der Entwickler zu nutzen und das Rad nicht neu zu erfinden.
 
SK. писал (а):
Schwerkraft001:

2: Warum funktioniert das Schema NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , wobei !OC! ein Vergleichsoperator ist, funktioniert nicht immer, selbst wenn man ihn direkt in if?
Das habe ich nicht gesagt. Genau so funktioniert es, und genau so sollten Sie es auch machen.

Hier finden Sie weitere Meinungen zu diesem Thema

'Wieder über den Vergleich zweier Doppelgänger', 1 Seite aus dem allerersten Beitrag!

Integer 24.12.2006 15:23

Leider ist die Konstruktion NormalizeDouble(x-y,Digits) nicht identisch mit der Konstruktion NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits)

Renat 24.12.2006 16:15

Und es sollte nicht identisch sein. Die erste Aussage ist richtig.

Ich denke, das Konstrukt ist
if (NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
und die Konstruktion
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sind identisch!

Was meinen Sie dazu?
 
gravity001:

Renat 24.12.2006 16:15

Und sie darf nicht identisch sein. Die erste ist richtig.

Ich denke, die Konstruktion
if(NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
und die Konstruktion
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sind identisch!

Was meinen Sie dazu?


Und die Meinung von Renat ist nicht interessant? Sie interessieren sich nicht für die Meinung des Geschäftsführers des Unternehmens, das MT entwickelt?

Oder sind Sie wie die alte Frau in Puschkins Märchen? Nur wollen-wollen-wollen-wollen! Vergiss nicht, wie das Märchen endet. "Der Fisch sagte nichts, wedelte mit dem Schwanz und schwamm ins blaue Meer hinaus. Er wartete lange am Meer auf eine Antwort. Er wartete nicht, sondern drehte sich zu der alten Frau um..."

 
SK. писал (а):
Die erste ist die Schwerkraft001:


Renat 24.12.2006 16:15

Und sie darf nicht identisch sein. Die erste Aussage ist richtig.

Ich denke, die Konstruktion
if(NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
und die Konstruktion
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sind identisch!

Was meinen Sie dazu?



Und die Meinung von Renat ist nicht interessant? Sie interessieren sich nicht für die Meinung des Geschäftsführers des Unternehmens, das MT entwickelt?


Oder sind Sie wie die alte Frau in Puschkins Märchen? Nur wollen-wollen-wollen-wollen! Vergiss nicht, wie das Märchen endet. "Der Fisch sagte nichts, wedelte mit dem Schwanz und schwamm ins blaue Meer hinaus. Er wartete lange Zeit am Meer auf eine Antwort. Er wartete nicht, sondern drehte sich zu der alten Frau um..."



Nun, Renat sagte, der erste Weg sei richtig und der zweite falsch, und Sie sagten, der zweite Weg sei richtig, richtig?

2? warum das Schema NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , wobei !OC! ein Vergleichsoperator ist, funktioniert nicht immer, selbst wenn man ihn direkt in if?
Das habe ich nicht gesagt. Genau so funktioniert es, und genau so sollte es auch gemacht werden.
 

Ich sagte dies im Sinne eines mehr oder weniger großen Vergleichs:

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

was bedeutet, dass Konstruktionen dieses Typs nicht immer funktionieren:

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

d.h. NormalizeDouble() sollte direkt in die Kopfzeile des Operators eingefügt werden, so nah wie möglich an der Stelle, wo die Vergleichsoperation berechnet wird.

Was die Meinung der Entwickler betrifft, so möchte ich sie nicht anzweifeln.

Und dann... ging es in diesem Thread um ein ganz anderes Konstrukt:

 
SK. писал (а):

Ich habe das gesagt und damit einen mehr oder weniger großen Vergleich angestellt:

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))
Ich habe nicht geprüft, ob es mehr oder weniger ist, aber ich habe auf Gleichheit geachtet.
Ich hatte Vergleichsfehler, als ich diese Konstruktion verwendete:

if (NormalizeDouble(x, digits) == NormalizeDouble(y, digits))
{
    ...
}
Warum, wissen Sie das nicht?
Grund der Beschwerde: