Ich kann zwar bei den Beispielprogrammen von VS2019 das Hello World-Programm erstellen, sehe aber keine Möglichkeit die Konsole dort zu deaktivieren.
Damit gebe ich dann mal auf beim Helfen. Ohne Makefiles o.Ä. ist es nur ein wenig spaßiges Raten.
Ich kann zwar bei den Beispielprogrammen von VS2019 das Hello World-Programm erstellen, sehe aber keine Möglichkeit die Konsole dort zu deaktivieren.
Damit gebe ich dann mal auf beim Helfen. Ohne Makefiles o.Ä. ist es nur ein wenig spaßiges Raten.
Wenn man alle Werte in einem Container aufaddieren will, ist es ja numerisch oft sinnvoll, so wenig Zwischenergebnisse wie möglich zu speichern. Gibt es da irgendwie was in der C++ Standard library, dass das für mich tut? Wenn ich mir zb std::accumulate anschaue bzw die mögliche Implentierung davon, scheint das ja nicht der Fall zu sein. Wenn ich die Containergröße vorher aber nicht weiß, kann ich das ganze natürlich auch nicht wirklich hardcoden. Außer natürlich mit einem Konzept, dass ich noch nicht kenne. Man könnte natürlich zb zweier oder dreierblöcke bilden, das hilft aber numerisch auch nur entsprechend viel dann.
Bzw gibt es da sonst noch andere Ansätze? Oder sehe ich mal wieder eine offensichtliche Lösung nicht
Also erst einmal ist festzuhalten, dass es bei N (unterschiedlichen) Zahlen immer N-1 Additionen sind egal wie man klammert.
Dir geht es aber vermutlich um die Rundungsfehler und da gibt es sehr viele Ansätze wie man sie minimieren kann.
Am simpelsten ist offensichtlich das Hochschrauben der Genauigkeit. Danach kommt das präferierte Addieren fast gleich großer Zahlen. Wenn man vorher (teuer) Sortiert, sollte das schon einigermaßen helfen. Grob Vorsortieren sollte auch reichen.
Ganz dunkel im Hinterkopf habe ich, dass es da sogar ein patentbehaftetes Verfahren gab, was sehr geringe Rundungsfehler macht. Das nur als Hinweis auf die mögliche Komplexität der Frage
Ja, das ist richtig
Bzgl der gleich großen Zahlen. Das habe ich auch schon getan, also ich habe alles sortiert. Ich vermute aber, das gleiche Größe meint, wie viele Stellen die Zahl vorm Komma hat, oder? Ich meine mich allerdings aus einer Vorlesung daran erinnern zu können, dass es auch 'schlecht' ist, gleich große negative und positive Zahlen zu addieren.Am simpelsten ist offensichtlich das Hochschrauben der Genauigkeit. Danach kommt das präferierte Addieren fast gleich großer Zahlen.
Ganz dunkel im Hinterkopf habe ich, dass es da sogar ein patentbehaftetes Verfahren gab, was sehr geringe Rundungsfehler macht. Das nur als Hinweis auf die mögliche Komplexität der Frage
Bei der Addition ähnlich großer Zahlen mit unterschiedlichem Vorzeichen wie
(A - (A+ε₁)) + (B - (B+ε₁)) + …
geht es darum, dass das Gesamtresultat einen viel höheren Exponenten als die Differenzen hat. Da gehen dann die vielen kleinen Differenzen verloren.
In dem Fall könnte man die Gesamtsumme in zwei Teile (M+m) splitten. Die neuen Werte werden in 'm' accumuliert. Wird der Wert zu groß verschiebt man einen Teil nach M.
Aber ob das schneller ist als gleich die Zwischenergebnisse mit höherer Genauigkeit zu speichern kann man im Allgemeinen nicht sagen
I had a problem, so I decided to use threads. prhave twI Now o oblems.
Heute erst gefunden
Mit Naturgesetzen kann man nicht verhandeln. --Harald Lesch
Ein Atomkrieg würde die Menschheit auslöschen. Hätte aber auch Nachteile.
Vielleicht kann dir das hier helfen: Kahan summation algorithm.
Danke, den hat mir mein Betreuer vorhin auch schon geschickt
Ich weiß übrigens, dass ich numerische Probleme habe, weil ich das ganze Programm auch noch mal in Python zum Debuggen geschrieben habe und da bekomme ich mit numpy leicht andere Ergebnisse raus. Python nutzt zwar auch nur double precision, allerdings vertraue ich dem natürlich zunächst mehr, als meiner eigenen Implementation.
Wenn du Python benutzt kannst du auch math.fsum verwenden bzw. als Vergleich heranziehen.
Ergibt es in C++ eigentlich Sinn, dass man beim Ausgabetyp einer Funktion den Referenzoperator & dazuschreibt? Ich glaube nicht, weil es erst bei der Variablendefinition entschieden wird, ob die Variable per Referenz definiert wird. Bsp.:
sollte eigentlich dasselbe bewirken wieCode:const string& GetConst() { static const string& s = "Hello World"; return s; } string s = GetConst();
Erst wenn manCode:const string GetConst() { static const string s = "Hello World"; return s; } string s = GetConst();
string& s = GetConst();
verwendet, ändert sich das Verhalten des Programms.
Ein Unterschied ist schon mal, dass string& s = GetConst(); bei der ersten Variante der Funktionsdefinition nicht erlaubt ist, oder?
Ich glaube du bist irritiert weil in deinem Beispiel auch noch der Zuweisungsoperator '=' eine Rolle spielt. Der ist ja bei Strings überladen.
string s = GetConst(); kopiert den Stringwert der Rückgabe von GetConst() in den von s gehaltenen Wert.
D.h. spätere Änderungen haben keinen Einfluss auf die statische Variable, die du in GetConst zurück gibst.
Vergleiche auch folgendes Beispiel:
Code:#include <string> #include <stdio.h> static std::string s = "Hello World"; std::string GetConst1() { return s; } std::string& GetConst2() { return s; } int main(){ //std::string a = GetConst1(); // ok //std::string& b = GetConst1(); // fail std::string a = GetConst2(); std::string& b = GetConst2(); a[0] = 'X'; b[0] = 'Y'; printf("%s %s %s\n", a.c_str(), b.c_str(), s.c_str()); // Ausgabe: Xello World Yello World Yello World return 0; }
Ja, wegen dem const gibt es dann Probleme. Es ging mir nur um das Beispiel.
Wenn ich deinen Beispielcode richtig verstanden habe, dann ist
string& GetConst
im Vergleich zu
string GetConst
flexibler handhabbar, weil die erste Version sowohl pass-by-ref als auch pass-by-value erlaubt, während die zweite nur pass-by-value erlaubt. Die zweite Version wäre also nur dann sinnvoll, wenn ich pass-by-ref unbedingt verhindern will (was allerdings sowieso nicht nötig wäre, wenn ich const hinzufüge). Von daher wäre der &-Operator beim Ausgabetyp einer Funktion eigentlich immer die bessere Variante, solange man bestimmte Variablen nicht als privat schützen will.
Geändert von Tiramisu (07. Juni 2020 um 01:02 Uhr)
Was für einen Standard verwendest du? Je nachdem solltest du dich mal mit der Move-Semantik beschäftigen.
Eine Funktion/Methode sollte besser nie eine Referenz zurückgeben. Denn man muss darauf achten, dass das Objekt, auf das referenziert wird, nach dem Funktionsaufruf noch da ist.
Und ein andere Grund (bei Methode), warum man das nicht tun sollte: warum muss eine Instanzvariable von außen modifiziert werden können? Das soll nur die Klasse tun können, andernfalls stimmt was mit dem Design nicht.
Ja, meistens ist es keine gute Idee, eine Referenz zurückzugeben.
Manchmal ist es nützlich, wenn man nur lesend auf einen langen String zugreift oder die Funktion sehr oft aufgerufen wird. Dann kann man Kopiervorgänge des Strings vermeiden, die sonst von String-Konstruktor ausgelöst werden.