Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools
Zurück   Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools > Metatrader 5 > Programmierung MQL5
Startseite Registrieren Hilfe Community Kalender Heutige Beiträge Suchen

Programmierung MQL5 Hier gehts rund ums Programmieren in MQL5.

Login
Benutzername:
Kennwort:


Statistik
Themen: 4978
Beiträge: 43690
Benutzer: 7.223
Aktive Benutzer: 75
Links: 84
Wir begrüßen unseren neuesten Benutzer: Sundaytrader
Mit 2.475 Benutzern waren die meisten Benutzer gleichzeitig online (16.01.20 um 22:38).
Neue Benutzer:
vor 5 Tagen
- Sundaytrad...
vor 5 Tagen
- TS_6
vor einer Woche
- Mane
vor 3 Wochen
- AlbertZiz
vor 3 Wochen
- michak

Onlineuser
'Wer ist online' anzeigen Benutzer: 0
Gäste: 424
Gesamt: 424
Team: 0
Team:  
Benutzer:  
Freunde anzeigen

Empfehlungen

Thema geschlossen
 
Themen-Optionen Thema durchsuchen Ansicht
  #1 (permalink)  
Alt 06.06.23
Elite Mitglied
 
Registriert seit: Apr 2011
Beiträge: 2.735
traderdoc befindet sich auf einem aufstrebenden Ast
Standard Subtraktionsrest bei double-Zahlen

Dass die Divison von Zahlen manchmal Werte mit 10 und mehr Kommastellen ergeben, z.B.

0.6/0.2 = 2.9999999999999996

ist bekannt, wenn auch unschön und hat mich so manches graues Haar gekostet.

Aber nun toppt das das o.g. noch um die Tatsache, dass auch die Subtraktion zweier double-Zahlen folgendes ergibt:

0.6 - 0.2 = 0.39999999999999997

Wer kann mir diesen Blödsinn sinnhaft erklären?

D.h. bei solch einer simplen Subtraktion müsste ich zum Erhalt der korrekten Differenz ein NormalizeDouble(0.6-0.2, 1) formulieren!!

Auch ein

MathMod(0.3-0.1, 0.1)

sollte eigentlich 0 ergeben.
Die reale Zahl dieser Operation beträgt aber 0.09999999999999998.

Das kann es doch aber nicht sein!

traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis.
  #2 (permalink)  
Alt 06.06.23
Elite Mitglied
 
Registriert seit: Apr 2011
Beiträge: 2.735
traderdoc befindet sich auf einem aufstrebenden Ast
Standard

Und nun wird es immer abenteuerlicher:

Bei den double-Variablen:
Lot_Max_Start = 0.1
Lot_Max_End = 0.3
Lot_Max_Step = 0.1

und

for (double lot_max = Lot_Max_Start; lot_max <= Lot_Max_End; lot_max += Lot_Max_Step) {
Print(lot_max);
}
Print(lot_max);

sollte eigentlich in den Printausgaben

0.1
0.2
0.3

stehen und was steht tatsächlich?

0.1
0.2
0.30000000000000004

Damit wird die o.g. Schleife nicht dreimal, sondern nur zweimal durchlaufen.

Was ist hier los???

traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis.
  #3 (permalink)  
Alt 07.06.23
Benutzerbild von Indikator-Trading
Premium Mitglied
 
Registriert seit: May 2020
Ort: Bielefeld
Beiträge: 345
Indikator-Trading befindet sich auf einem aufstrebenden Ast
Standard

Die Anzahl an Schleifendurchläufe machst du besser immer mit Integer. Ansonsten kannst du NormalizeDouble() nutzen, damit du immer sicher auf eine bestimmte Nachkommastelle rundest.
  #4 (permalink)  
Alt 07.06.23
Elite Mitglied
 
Registriert seit: Apr 2011
Beiträge: 2.735
traderdoc befindet sich auf einem aufstrebenden Ast
Standard

Ja, das ist mir schon klar, danke.
Aber wieso kann MQL5 double-Zahlen nicht ordentlich subtrahieren bzw. auch addieren, denn bei 0.1 + 0.2 + 0.3 kommt eben nicht exakt 0.3 raus, sondern 0.30000000000000004. Das mag häufig unerheblich sein, aber gerade bei if-Abfragen mit Vergleichswerten gibt es z.T. keien korrekten Entscheidungen.

Das kann es doch nicht sein, dass man bei jeder double-Operation NormalizeDouble() benutzen muss, zumal manchmal nicht immer die Kommastelle
bekannt ist.

traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis.
  #5 (permalink)  
Alt 08.06.23
Premium Mitglied
 
Registriert seit: Jun 2013
Beiträge: 364
Ca$hDigger befindet sich auf einem aufstrebenden Ast
Standard

Hallo traderdoc damit muss man leben und es ist (leider) alles normal denn Gleitkommazahlen können nicht präzise dargestellt werden, da sie in Computerarithmetik als binäre Zahlen gespeichert werden müssen. Die meisten Gleitkommazahlen können nicht direkt als Binärzahl mit endlicher Länge dargestellt werden, was dazu führt, dass eine binäre Gleitkommazahl nur eine Annäherung an die tatsächliche Dezimalzahl ist. Dies führt zu Rundungsfehlern und Ungenauigkeiten bei der Durchführung von Berechnungen mit Gleitkommazahlen. Zudem gibt es auch teilweise Limitierungen der Anzahl der Bits, die zur Darstellung von Gleitkommazahlen zur Verfügung stehen.
Genau genommen bringt NormalizeDouble() auch nur wieder ein double als Rückgabewert und ist kein "genauer" Integer und damit potentiell "ungenau". Gerade in Schleifen niemals eine Gleitkommazahl nutzen!, immer zuvor ein Casting/Typumwandlung machen zu einem Integer.
Gruß
  #6 (permalink)  
Alt 08.06.23
Elite Mitglied
 
Registriert seit: Apr 2011
Beiträge: 2.735
traderdoc befindet sich auf einem aufstrebenden Ast
Standard

Aber was nutzt mir der Integer in einer Schleife als Schleifenzähler, wenn ich dann die double-Zahlen aufaddieren muss und bei 0.1 + 0.1 + 0.1 eben nicht 0.3, sondern 0.30000000000000004 rauskommt und nach Abfrage, ob dieser Wert <= 0.3 ist mir dann ein false gibt und die Schleife zwar 3mal angefahren wird, aber mit der if-Abfrage die 3. Schleife doch nicht durchläuft.
Die Benutzung von NormalizDouble(), v.a. bei Divisionen mache ich doch schon seit anfang an, aber bei einer Addition bzw. Subtraktion hätte ich nicht vermutet, dass das eine krumme Zahl ergibt.

Das ist alles frustrierend.

traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis.
  #7 (permalink)  
Alt 08.06.23
Premium Mitglied
 
Registriert seit: Jun 2013
Beiträge: 364
Ca$hDigger befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von traderdoc Beitrag anzeigen
aber bei einer Addition bzw. Subtraktion hätte ich nicht vermutet, dass das eine krumme Zahl ergibt.
Das ist normal und gilt für alle Rechnungen. Sobald man aus einer Rechnung ein Ergebnis erhält hat man es direkt mit diesen natürlichen Ungenauigkeiten zu tun und muss damit umgehen.

Ich habe erst auf den zweiten Blick gesehen was alles in der Schleife los ist, dann ist die Idee mit dem double dort nachvollziehbar aber es sind dann da sogar zwei Gleitkomma Aspekte :
1. Ergebnisse aus Rechnungen: kann man wie gehabt mit NormalizeDouble() glatt bügeln.
2. Vergleiche: der <= trägt neben der kleinerAls auch eine isEqual Logik in sich, dies auch beachten, denn der check ob zwei Gleitkommazahlen gleich sind, ist auch eine Stolperfalle. Ein Abgleich wie isEqual oder auch isZero kann man mit einer Funktion lösen, Ansätze sind hier beschrieben:
https://www.mql5.com/en/forum/156466
Es kann sein, dass mit NormalizeDouble() auch hin und wieder ein Abgleich ohne sowas funktioniert, ich würde mich aber nicht 100% darauf verlassen denn NormalizeDouble() liefert immer double zurück und das unterliegt nun mal immer der nicht präzisen Darstellung. Ich würde daher zwei doubles nicht ohne solche isEqual Funktionen vergleichen.

Letztendlich ist es wichtig, sich bewusst zu sein, dass Gleitkommazahlen in der Programmierung eine begrenzte Genauigkeit aufweisen und dass dies bei der Verarbeitung und Verwendung von Zahlen Berücksichtigung finden muss.
Was wir als Mensch wollen sind eigentlich Ergebnisse wie bei der dezimalen Handrechnung also die dezimale Festkommaarithmetik aber die ganzen Programmiersprachen bieten, zumindest nicht ohne Weiteres, leider kein solches Festkommaformat.
  #8 (permalink)  
Alt 09.06.23
Elite Mitglied
 
Registriert seit: Apr 2011
Beiträge: 2.735
traderdoc befindet sich auf einem aufstrebenden Ast
Standard

Hallo Cas$Digger,
danke für Deine Ausführungen.

traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis.
Thema geschlossen

Lesezeichen


Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus




Alle Zeitangaben in WEZ +2. Es ist jetzt 07:58 Uhr.





Suchmaschine - Reisen - Wavesnode - Facebook Forum - Spam Firewall
-----------------------------------------------------------------------------------------------------------------------------
Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
SEO by vBSEO 3.6.1
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum
MetaTrader bzw. MetaTrader 4 und MetaTrader 5 sind eingetragene Marken der MetaQuotes Software Corp.
-----------------------------------------------------------------------------------------------------------------------------