Fehler, Irrtümer, Fragen - Seite 711

 
sergeev:
Verwenden Sie die Klassen.

Ja, das ist richtig. Das war mir nicht klar. Ich erinnere mich nicht einmal daran, es wurde schon einmal vorgeschlagen.

So war es dann auch:

struct Buff { double b[]; };
//---
Buff lbuff[];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int i=2,j=1000;
//---
   ArrayResize(lbuff,i);
   ArrayResize(lbuff[0].b,j);
   ArrayResize(lbuff[1].b,j);
  }
Rosh:
Werfen Sie einen Blick auf Überladen Operationen Abschnitt zum Beispiel für CMatrix Klasse, vielleicht wird dies Ihnen passen.
Danke, ich werde es studieren.
 
Rosh:

Eine reelle Zahl wird nämlich mit höchstens 17 signifikanten Ziffern im Speicher abgelegt.

Probieren Sie dieses Beispiel aus, um den Unterschied zu spüren:

Wir werden die Beschreibung in der Hilfe korrigieren.

Ja, Renat hat bereits oben erklärt, dass Print()Daten vom Typ double auf 4, nicht auf 16 Dezimalstellen nach dem Punkt genau ausgibt.Das war der springende Punkt aus der Sicht der Nutzer.

 
Yedelkin:

Ja, Renat hat bereits oben erklärt, dass Print()Daten vom Typ double auf 4, nicht auf 16 Dezimalstellen nach dem Komma ausgibt.Das war das Problem aus der Sicht des Benutzers.

Nein, Print() druckt im Format %.16G, was bedeutet, dass versucht wird, eine Zahl mit einem Punkt und 16 signifikanten Ziffern zu drucken. In diesem Fall ist die gespeicherte Zahl 199,99999999999997, die 17 signifikante Stellen hat (3 Stellen vor dem Dezimalpunkt + 14 Stellen nach dem Dezimalpunkt). Wenn ich versuche, 16 Ziffern zu drucken, beginnt die Rundung, 7 wird auf 10 gerundet, eine geht auf die höhere Ziffer, und 9 ist da. Das Domino-Prinzip beginnt, die gedruckte Zahl wird auf 200 gerundet.

Versuchen Sie ein Beispiel:

void OnStart()
  {
   double a,b;

   a=7.0/200.0;
   b=7.0/a;
   Print("Print(b)=",b);
   Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));
   double epsilon=MathPow(10,-13);
   Print("-------- После вычитания ",epsilon,"---------");
   b=b-epsilon;
   Print("Print(b)=",b);
   Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));

   
  }

Sehen Sie sich PrintFormat() an .

 
Rosh:

Nein, Print() gibt im Format %.16G aus, was bedeutet, dass versucht wird, eine Zahl mit einem Punkt und 16 signifikanten Ziffern auszugeben. In diesem Fall ist die gespeicherte Zahl 199,99999999999997, die 17 signifikante Stellen hat (3 Stellen vor dem Dezimalpunkt + 14 Stellen nach dem Dezimalpunkt). Wenn ich versuche, 16 Ziffern auszudrucken, beginnt die Rundung, 7 wird auf 10 gerundet, man geht zur nächsthöheren Ziffer, und 9 ist da. Das Domino-Prinzip beginnt, die ausgedruckte Zahl wird auf 200 gerundet.

Schauen Sie sich PrintFormat() an.

Jetzt verstehe ich, warum wir uns auf die Anzahl der gespeicherten signifikanten Zahlen konzentrieren.

...Wenn aber eine reelle Zahl mit nicht mehr als 17 signifikanten Ziffern gespeichertwird (in unserem Fall ist es 199,99999999999997), woher kommen dann die signifikanten Ziffern?

MP 0 victorg2 (EURUSD,M1) 11:04:42 Druck(DoubleToString(b,16))=199.999999999999999716

? (Ich habe 19 Entladungen gezählt)
 

"In Kampfsituationen kann die Zahl der Pi bis zu vier betragen".

DoubleToString funktioniert etwas anders als die Formatierung im Drucker (die dem CRT überlassen wird)

DoubleToString konvertiert ganzzahlige und gebrochene Teile separat und mit einem etwas schnelleren Algorithmus als die Standardformatierung in Zeichenketten.

Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
  • www.mql5.com
Основы языка / Типы данных / Вещественные типы (double, float) - Документация по MQL5
 
stringo:

Bei DoubleToString werden der ganzzahlige und der gebrochene Teil getrennt und mit einem etwas schnelleren Algorithmus als bei der Standardformatierung in Zeichenketten umgewandelt.

Doch dann stellt sich heraus, dass etwas mehr als 17 signifikante Ziffern im Speicher abgelegt sind . Woher kämen sonst die ganzzahligen und gebrochenen Teile für die Umwandlung in Zeichenketten? Das heißt, unabhängig davon, ob es sich um Print() oder DoubleToString() handelt, erhalten sie ihre Daten von irgendwoher (wenn wir speziell über die Speicherung "im Speicher mit nicht mehr als 17 signifikanten Ziffern" sprechen).

...Vielleicht habe ich mich aber auch in der Formulierung "Speichern im Speicher" verfangen und verstehe es nicht ganz richtig, weil ich nicht weiß, wie man reelle Zahlen speichert.

 
Yedelkin:

Aber dann stellt sich heraus, dass etwas mehr als 17 signifikante Ziffern im Speicher vorhanden sind . Woher kommen sonst die ganzzahligen und gebrochenen Teile für die Umwandlung in Zeichenketten? D.h. ob Print() oder DoubleToString(), sie beziehen ihre Daten von irgendwoher (wenn wir speziell über die Speicherung "im Speicher mit nicht mehr als 17 signifikanten Stellen" sprechen).

...Vielleicht bin ich aber auch nur dem Begriff "Speichern im Speicher" verfallen und verstehe ihn nicht ganz richtig, weil ich nicht weiß, wie man reelle Zahlen speichert.

Manchmal werden bis zu 20 signifikante Ziffern gespeichert, aber das ist nicht garantiert. Und im Allgemeinen gilt: Je größer die Zahl im ganzzahligen Teil ist, desto ungenauer ist sie im gebrochenen Teil.

Warum brauchen Sie 16 Dezimalstellen? Akademisches Interesse?

Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
Документация по MQL5: Основы языка / Типы данных / Вещественные типы (double, float)
  • www.mql5.com
Основы языка / Типы данных / Вещественные типы (double, float) - Документация по MQL5
 
stringo:

Manchmal werden bis zu 20 signifikante Ziffern gespeichert, aber das ist nicht garantiert. Und im Allgemeinen gilt: Je größer die Zahl im ganzzahligen Teil ist, desto ungenauer ist sie im gebrochenen Teil.

Warum brauchen Sie 16 Dezimalstellen? Akademisches Interesse?

:) Um das Telefon nicht zu verderben, sollten wir uns die Vorgeschichte ansehen.

Hier stellte victorg eine Frage zur Arbeit der Funktion Print() und den von ihr erzeugten Werten.

Hier habe ich ihm den Grund gezeigt.

Da er sich nicht mit den Problemen der Print()-Funktion herumschlagen wollte,

Ich hatte die Frechheit, darauf hinzuweisen, dass in der Beschreibung der Funktion Print()steht, dass "Daten vom Typ Double mit einer Genauigkeit von 16 Dezimalstellen nach dem Komma gedruckt werden. Tatsächlichstellte sich heraus, dass die Funktion Print() etwas gerundete Daten mit einem konkreten Beispiel im Anhangausgibt .

Daraufhin entbrannte eine hitzige Diskussion, an deren Ende niemand in der Lage war, mein Beispiel zu widerlegen, und Renat skizzierte die erste Version und sagte, dass das Nachschlagewerk korrigiert werden würde.

Einige Tage später legte Roche eine zweite Version vor, in der die Zahl 17 erwähnt wurde.

Nachdem Sie sich in die Diskussion eingeschaltet hatten, schlugen Sie eine dritte Version vor, nämlich die: "In DoubleToString werden der ganzzahlige und der gebrochene Teil getrennt in Zeichenketten umgewandelt, und zwar mit einem etwas schnelleren Algorithmus als bei der Standardformatierung", d.h. es hat sich bereits herausgestellt, dass es eine Frage der Algorithmusgeschwindigkeit ist.

Dann habe ich Sie darauf aufmerksam gemacht, dass es sich im Allgemeinen um die Größe der gespeicherten Zahl aus der zweiten Version von Roche handelt.

stringo:

Warum brauchen Sie 16 Dezimalstellen? Akademisches Interesse?

Jetzt können Sie diese Fragen beantworten. Ich habe ein Beispiel gegeben, bei dem die Funktion Print() gerundete Daten ausgibt. Ich habe nicht nach den Gründen für ein solches Verhalten gefragt. Mein Beispiel wurde nicht widerlegt, sondern mir wurde lediglich geraten, eine andere Funktion zu verwenden, und ich begann, die Gründe dafür zu erläutern. Und unter diesen Erklärungen tauchte die Erwähnung von 16 (17) Dezimalstellen auf. Da mir in diesen Erklärungen nicht alles klar war, stellte ich "nebenbei" Fragen. - Es war also nicht einmal ein akademisches Interesse meinerseits, sondern einfach der Wunsch zu verstehen, was die Idee mir vermitteln wollte.

 
Yedelkin:

. . . Es ist also nicht einmal ein akademisches Interesse meinerseits, sondern nur der Wunsch zu verstehen, welche Botschaft ich zu vermitteln versuchte.

Ich könnte nicht mehr zustimmen. Das akademische Interesse hat damit nichts zu tun.

Lesen Sie"reale Zahl" in der Dokumentation. Nach dem IEEE-Standard 754 gibt es in der Tabelle für Double 15 signifikante Ziffern. Unter Berücksichtigung dieser Tatsache gibt es vier Optionen - 15, 16, 17 signifikante Stellen und eine Option, bei der der ganzzahlige Teil und der gebrochene Teil getrennt gespeichert werden. Aber so funktioniert das nicht! Was hat das akademische Interesse damit zu tun? Es geht eher um elementare formale Logik, die übrigens die Grundlage dieser Programmiersprache ist.

Meines Erachtens sollte der Programmierer Programme schreiben und nicht den Compiler untersuchen.

PS

Ich möchte diese Gelegenheit nutzen, um etwas klarzustellen:

Wenn ich ein dynamisches Array mit der Funktion ArrayResize() vergrößere, ist dann garantiert, dass die Daten, die zuvor darin platziert wurden, erhalten bleiben? Vielleicht sollte dieser Punkt explizit in der Dokumentation erwähnt werden (in der Beschreibung der Funktion ArrayResize()).Falls jemand etwas weiß, bitte ich um einen Hinweis.

 
victorg:

Wenn ich die Größe eines dynamischen Arrays mit ArrayResize() vergrößere, ist dann garantiert, dass die Daten, die zuvor darin platziert wurden, erhalten bleiben? Vielleicht sollte dieser Punkt in der Dokumentation explizit erwähnt werden (in der Beschreibung der Funktion ArrayResize()).Falls jemand etwas weiß, bitte ich um einen Hinweis.

Sie werden es sein, wenn die Größe vergrößert wird, sonst hat eine solche Funktion keinen Sinn.
Grund der Beschwerde: