Schleife statt mehrfache Rechnung, wie anstellen? Quadratwurzel Newton-Verfahren
-
Hallo, ich bin eine Erstssemester Wirtschaftsinformatik Studentin ohne Vorkenntnisse in C++. Mein Prof erklärt leider nur teilweise das, was er von uns in bewerteten Aufgaben verlant. 2 versemmelte Aufgaben = durchgefallen durch das Modul versuchs im nächsten Semester nochmal.
So die Aufgabe habe ich zwar versemmelt, mein Prof will, dass wir das in einer Schleife ausrechnen, kann ich aber nicht - noch nicht. Daher bitte ich euch um Hilfe mir das ganze mal etwas eleganter in einer Schleife zu gestalten. Das Programm tut was es soll, es funktioniert - wurde in etwa so abgegeben, erfüllt nur leider nicht die gewünschte Schleife, die der Prof haben will. Änderungen bei der Abgabe kann ich NICHT mehr vornehmen, d.h. es hilft nur noch mir um das ganze zu verstehen.

Um das aber in Zukunft gleich eleganter gestalten zu können - ich versuche mich in der Freizeit gerne an anderen Aufgabenstellungen um das (dann hoffentlich) gelernte noch mal anzuwenden.Hier mal der Code:
#include <iostream> #include <cmath> #include <math.h> #include <iomanip> using namespace std; int integerA; int main() { double x1 = 0.00, x0 = 0.00, y, x2, x3, x4; while (integerA <= 1) { cout << "Willkommen zu einem kleinen Programm zur Berechnung der Quadratwurzel.\n\n" << "Hierzu benoetige ich den Wert der Zahl x, diese muss unbedingt positiv sein.\n" << "Hast du deine Zahl eingegeben, bestaetige bitte mit Enter.\n"; cin >> y; x0 = y / 4; x1 = (x0 - (((x0*x0) - y) / (2 * x0))); cout << "\n" << "Die erste Annaeherung ist " << x1 << ".\n\n"; x2 = (x1 - (((x1*x1) - y) / (2 * x1))); cout << "\n" << "Die zweite Annaeherung ist " << x2 << ".\n\n"; x3 = (x2 - (((x2*x2) - y) / (2 * x2))); cout << "\n" << "Die dritte Annaeherung ist " << x3 << ".\n\n"; x4 = (x3 - (((x3*x3) - y) / (2 * x3))); cout << "\n" << "Die vierte Annaeherung ist " << x4 << "." << "\n\n\n\n" << "++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" << "Die Quadratwurzel von " << y << " ist " << x4 << "." << "\n\n" << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" << "Wenn du weitere Berechnungen durchfuehren moechtest, \ndann gib jetzt bitte die 1 ein," << "zum Beenden eine beliebige andere \nZahl und bestaetige mit Enter.\n"; cin >> integerA; } return 0; }Explizit geht es mir nur um folgende Zeilen:
x1 = (x0 - (((x0*x0) - y) / (2 * x0))); cout << "\n" << "Die erste Annaeherung ist " << x1 << ".\n\n"; x2 = (x1 - (((x1*x1) - y) / (2 * x1))); cout << "\n" << "Die zweite Annaeherung ist " << x2 << ".\n\n"; x3 = (x2 - (((x2*x2) - y) / (2 * x2))); cout << "\n" << "Die dritte Annaeherung ist " << x3 << ".\n\n"; x4 = (x3 - (((x3*x3) - y) / (2 * x3))); cout << "\n" << "Die vierte Annaeherung ist " << x4 << "." << "\n\n\n\n"Diese sollen in einer Schleife durchlaufen, bis sie etwa der Quadratwurzel entsprechen... also iwas mit einer Genauigkeit, hab ich nur in der Vorlesung leider nichts von gehört, geschweige denn im Script gelesen wie wir das anstellen sollen. Und ja ich bemühe mich auch um ein Selbststudium mit Büchern, ein Buch habe ich vorliegen ein weiteres ist auf dem Postweg und morgen hoffentlich da, doch so schnell bekomme ich die Bücher leider nicht durchgeackert wie ich das Wissen in 1 Vorlesung pro Woche bräuchte...
Bin für jede Hilfe sehr dankbar, da ich nur mit dem Wissen um die Schleife meine andere Aufgabe überhaupt in Angriff nehmen kann.
-
Wie du siehst, wiederholt sich dort 4x der gleiche Code. Daher pack das einfach in eine Schleife. Beispielsweise macht dieser Code exakt das gleiche, wie dein eigener:
double x = y / 4; unsigned i = 0; while (i < 4) { ++i; x = (x - (((x*x) - y) / (2 * x))); cout << "\n" << "Die " << i << ". Annaeherung ist " << x << ".\n\n"; }Klar, wie das funktioniert?
Die Abbruchbedingung ist aber eher bescheiden. Woher soll man im Voraus wissen, ob 4 Durchläufe optimal sind? Daher prüfst du bei jedem Durchlauf, wie nahe du dem Ergebnis bereits bist:
x*x-ygibt dir eine Metrik, wie nahe du am echten Wert bist. Den echten Wert wird man aber oft nie genau erreichen, also vergleicht man diesen Wert mit einer vorgegebenen Toleranz. Ist man unterhalb der Toleranzschwelle, ist man fertig. Da die Abweichung sowohl positiv als auch negativ sein könnte, nehmen wir dazu den Absolutbetrag (abs):while(abs(x*x - y) > tolerance)Aber das ist offensichtlich noch doof, da die Toleranz eine feste Zahl ist. Wenn wir aber die Wurzel von 0.00004 suchen, dann wollen wir sicherlich eine andere Schwelle als wenn wir die Wurzel von 99999999999 suchen. Daher teilen wir noch durch y, damit die Toleranz relativ gemessen wird:
while (abs(x*x - y) / y > tolerance)Insgesamt also:
#include <iostream> #include <cmath> using namespace std; int main() { int integerA; while (integerA <= 1) { cout << "Willkommen zu einem kleinen Programm zur Berechnung der Quadratwurzel.\n\n" << "Hierzu benoetige ich den Wert der Zahl x, diese muss unbedingt positiv sein.\n" << "Hast du deine Zahl eingegeben, bestaetige bitte mit Enter.\n"; double y; cin >> y; double x = y / 4; unsigned i = 0; const double tolerance = 1e-7; while (abs(x*x - y) / y > tolerance) { ++i; x = (x - (((x*x) - y) / (2 * x))); cout << "\n" << "Die " << i << ". Annaeherung ist " << x << ".\n\n"; } cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" << "Die Quadratwurzel von " << y << " ist " << x << "." << "\n\n" << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" << "Wenn du weitere Berechnungen durchfuehren moechtest, \ndann gib jetzt bitte die 1 ein," << "zum Beenden eine beliebige andere \nZahl und bestaetige mit Enter.\n"; cin >> integerA; } }
-
Hallo SeppJ, vielen dank für deine Antwort. Sicher hilft mir das weiter, jetzt muss ich mir nur noch unbekannte Schlüsselwörter raussuchen - dafür gibts ja zum Glück genügend Material im Web, damit dann alles restlos klar wird.
Meine nächste Aufgabe ist es jetzt mit Klassen zu arbeiten und in diesem Sinne wieder Annäherungen zu berechnen, diesmal allerdings die 3. Wurzel aus X - wenn ich hier alles verstanden habe, sollte ich das ja dann umsetzen können.
Das einzig mir unverständliche, auch nach Überlegung was das sein könnte (Schlüsselwörter sind nun verstanden und in einem kleinen Notizheft vermerkt) ist der mathematische Ausdruck 1e-7 sowas hab ich zwar irgendwo mal gesehen, erinnere mich aber nicht mehr daran was das ist und was es im endeffekt bedeutet. sieht für mich nach ner Rechnung im Hexadezimalsystem aus, wirds ja aber kaum sein, oder?
-
xey oder xEy steht für "x * 10 hoch y". Hier also "1 * 10 hoch -7". Ich wollte bloß nicht 0.000001 schreiben müssen. (und jetzt musste ich am Ende noch viel mehr schreiben :p )
-
Danke dir, jetzt hab ich alles verstanden
