C++ Newtons Quadratwurzeln mit C++

Faralis

Cadet 1st Year
Registriert
Apr. 2015
Beiträge
8
Hallo, mal wieder meine Probleme mit der Aufgabe vom Professor - und zwar sollen wir per Newtons Methode die Quadratwurzel, in einer erweiterten Aufgabe auch die 3. Wurzel einer Zahl X ausrechnen... alles soll iterativ :freak: (welch tolles Wort, hatte ich vorher noch nie gehört) ausgerechnet und auf dem Bildschirm ausgegeben werden.
Leider kommt bei mir wenn ich die Quadratwurzel von 4 also 2² ziehen lasse nicht 2 sondern 2,5 raus :confused_alt:
Die Formel zur Berechnung habe ich mir auch aus lauter Zeitdruck und Verzweiflung im Internet rausgefischt - nachfolgend und für mich, die Abgabefrist ist seit über einer Stunde vorbei, möchte ich das ganze aber noch korrigieren damit es funktioniert und sehen, wo mein Fehler war, damit ich ihn in der Hausaufgabe umgehen kann.

Wahrscheinlich sieht das ganze auch wieder sehr nach einer Holzhacker-Methode zum Lösen der Aufgabe aus, aber ich kann es noch nicht elegant bitte um Rücksicht, Bücher zum Selbststudium sind vorhanden bzw auf dem Postweg.

Code:
#include <iostream>
using namespace std;

#include <cmath>
using namespace std;

#include <iomanip>
using namespace std;

int integerA;

int main()
{

	double x1 = 0.00, x0 = 0.00, y;

	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;
		cout << "x0 = " << x0 << setprecision(10) << endl;

		x1 = (x0 - (((x0*x0) - y) / (2 * x0)));
		x0 = x1;
		
		cout << "\n"
		 	 << "Die Loesung ist \n"
			 << "x1 =" << x1 << setprecision(10) << "\n"
			 << "x0 =" << x0 << setprecision(10) << "\n"
			 << endl;


	
		cout << "Die Quadratwurzel von " << y << " ist " << x1 << "."
			 << "\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;
}

Kann mir jemand helfen und mir sagen, wo da das Problem zum einen in der Rechnung liegt und dann, wo ich mehr Schritte und iterativ in einer Schleife den Schnodder ausrechnen soll? Ich komme leider nicht weiter...
 
Du scheinst das Prinzip der iterativen Näherung noch nicht verinnerlicht zu haben. Lies z.B. hier darüber nach. Wenn du verstanden hast, warum x1 (höchstwahrscheinlich) nicht die Lösung deiner Rechnung ist, dann solltest du auch darauf kommen, wie du dein Programm ändern musst.
 
Du sowas rechne ich normalerweise auch mit dem Taschenrechner nicht mit dem PC oO' mal abgesehen davon, dass ich mit dem Wikipedia Link nichts anfangen kann da hing ich heute morgen auch schon...
 
Iterativ bedeutet in dem Zusammenhang nicht mehr und nicht weniger, als alle Berechnungsschritte nacheinander (etwa in einem Schleifenkonstrukt) durchzugehen, oder anders ausgedrückt: aufeinander aufbauend (im Gegensatz dazu steht die rekursive Umsetzung).

In deinem konkreten Fall, sollst du wir vermutlich überlegen, wie die Berechnung der einzelnen Zwischenstufen für die Ergebnisannäherung über eine Schleife berechnet bekommst - bei deinem Code würde ich mir da einmal die Zeilen 27/28 für anschauen.
 
Damit hast du ausreichen Hilfe für deine Hausaufgabe bekommen.
Ich weiß nicht was du studierst, aber irgendetwas mit technisches wird es schon sein. Der Begriff iterativ ist da ziemlich gängig.
​Wenn es schon daran scheitert, würde ich mir Gedanken über das richtige Studienfach machen.

Viel wichtiger ist aber folgendes; Computerbase ist kein Hausaufgabenboard.
 
phil. schrieb:
Der Begriff iterativ ist da ziemlich gängig.
​Wenn es schon daran scheitert, würde ich mir Gedanken über das richtige Studienfach machen.

Viel wichtiger ist aber folgendes; Computerbase ist kein Hausaufgabenboard.
Verzeih bitte meinen sarkastischen Tonfall, aber ich bin ein Erstsemester an einer Fachhochschule, der seine Fachhochschulreife im Wirtschaftsbereich gemacht hat und im Studiengang Wirtschaftsinformatik sitzt - und daher nicht zwingend den Ausdruck iterativ kennt - wurde in weder in unserem Mathelehrbuch noch von unseren Lehrern jemals genutzt, woher also das Wissen um die Bedeutung des Wortes?
Ich sagte bereits ich bin ein C++ Neuling, erstes Semester und der Prof erklärt nur die Hälfte von dem was er uns an Aufgaben gibt, wenn überhaupt so viel. In meinem Jahrgang sitzen einige, die schon Erfahrung haben und dann wiederum welche, die nicht wirklich mitkommen so wie ich, weil sie entweder mehr aus dem wirtschaftlichen Bereich stammen oder aber direkt vom Gymnasium kommen und nie was mit Informatik am Hut hatten.
Es geht mir nicht mal mehr darum die Hausaufgabe abzugeben, das ist vor einigen Stunden schon geschehen mit all ihren Fehlern und Änderungen kann ich seitdem nicht mehr vornehmen. Es geht mir rein darum zu verstehen, was falsch läuft, wieso es falsch läuft und wie ich es richtig mache... mit dem Script meines Professors komme ich nicht allzu weit, da stehen die Sachen alle Kreuz und Quer drin wenn ich das mit dem Buch vergleiche, dass ich mir bereits geholt habe - aber da ich mehr als nur dieses eine Modul habe für das ich lernen muss, kann ich das nicht binnen weniger Tage durchprügeln. Ein weiteres Buch ist unterwegs in der Hoffnung, dass ich damit schneller lernen kann... in meinem privaten Umfeld gibt es leider niemanden den ich damit belästigen könnte, somit muss ich mir online Hilfe suchen und da ich selbst so nicht mehr weiter kam fragte ich schlussendlich hier nach Hilfe, was denn an dem Quellcode falsch sei. Ich wollte nicht, dass sich jemand hier hinsetzt und einen völlig neuen Quellcode für mich schreibt, das möchte ich wenn schon selbst tun - sonst lerne ich ja auch wieder nichts daraus.
 
Ohne dem TE zu nahe treten zu wollen, eine Informatikvorlesung zum Thema C++ Programmierung ohne die Grundbegriffe Iteration und Rekursion gibt es wohl kaum. Entweder wurde da etwas vom TE verpasst oder er hat schlicht das falsche Studienfach gewählt.
 
Unbekannte Begriffe könnte man tatsächlich einfach nachschlagen. Trotzdem - muss dieser aggressiv-pampige Tonfall in den Antworten sein? Ein Hinweis auf den hier reicht doch.

Ab davon:
Code:
#include <iostream>
using namespace std;
 
#include <cmath>
using namespace std;
 
#include <iomanip>
using namespace std;

Ugh. Wurde euch das wirklich irgendwo so beigebracht? Wenn ja, hau das bitte umgehend dem Verantwortlichen um die Ohren, denn einerseits ist "using namespace std" ohnehin böse, andererseits reicht es auch, das 1x in den Scope zu schreiben.
 
Zuletzt bearbeitet:
Ich hab jetzt nicht die Zeit es ausführlicher zu beantworten aber ich kann dir einen besseren Hinweis in die Richtung geben:
Die Idee dieses Verfahrens ist, dass es mit einem "Rateversucht" anfängt und diesen dann Schritt für Schritt verbessert.
Dh du brauchst eine maß dafür, wie gut die bisherige Lösung ist (wird auch allgemeiner "Abbruchbedingung" genannt) und eben eine Schleife wie zB while, welche immer wieder und wieder versucht die aktuelle Lösung durch eine bessere zu ersetzen. Die Schleife muss natürlich nicht nur enden, wenn die Wurzel EXAKT berechnet wurde sondern wenn die aktuelle Lösung "dicht genug" an der exakten Lösung dran liegt.
Dh deine Berechnung trifft nach dem ersten Berechnungsschritt zwar 2,5 was ja auch in der Nähe liegt aber was in deinem Programm komplett fehlt ist die Wiederholung. Eigentlich gibts bei dir schon eine Schleife aber innerhalb deiner while berechnest du genau einen Iterationsschritt und gibst dessen Ergebnis aus. Stattdessen solltest du in der while ($Bedingung) prüfen, ob das gefundene Ergebnis gut genug ist und - wenn notwendig - das bisherige durch einen Schritt des Newton-Verfahrens verbessern. Nach einigen Schritten befindet die Bedingung in der while() dann hoffentlich, dass die gefundene Lösung dicht genug an der exakten Lösung liegt und bricht ab.

1x using namespace std; reicht übrigens.
 
Nein das ist auf die Verzweiflung nach Stunden des Suchens gewachsen... iwann bau ich auch nur noch Mist, vorallem wenn ich durch die Blumen gesagt bekomme, dass ich ja zu doof für den Studiengang sei - was kann ich dafür wenn bestimmte Begriffe in der 3. Vorlesung des 1. Semester noch nicht aufgetaucht sind?? Es is ne Anfängervorlesung die aber iwie nicht so ganz für Anfänger konzipiert ist... ich sitze den ganzen Tag schon halb heulend vor dem Quellcode und komme eher mathematisch nicht weiter.
Sowas hab ich vorher auf nem Blatt Papier und mit dem Taschenrechner gemacht - aber das ist schon eine ganze Weile her und wie das genau noch mal geht ist zum einen aus dem Hirnkasten wieder raus, käme auch sicher wieder rein - bringt mir aber nichts, da ich es ALLEINE nicht umsetzen kann in Programmiersprache... da mir hier das Wissen fehlt.
Immerhin weiß ich jetzt etwas weiter und kann versuchen zumindest die Bedingung hinzubiegen aber... ich geb die Hoffnung bei der scharfen Kritik wirklich bald auf.
Ergänzung ()

Naja Thema erledigt... zwar wieder unelegant aber immerhin gelöst. Danke kuddlmuddl für den Hinweis, der hat mich zu ner Lösung, wenn gleich sie auch sehr unelegant und eher eine Holzhacker-Variante ist geführt.
 
Das Newton Verfahren ist eine Vorgehensweise aus der numerischen Mathematik, welches approximativ (näherungsweise) die Nullstellen einer reellen Funktion berechnet.

In deinem Fall hat die Funktion die Form

f(x) = x^2 - z

wobei z die Zahl ist, von der du die Wurzel wissen möchtest, denn die Wurzel ist die Nullstelle dieser Funktion.
Im Fall z = 2 erhälst du

f(x) = x^2 - 2

Weiters benötigst du die erste Ableitung von f(x), also f'(x), dies ist

f'(x) = 2*x


Das Newton Verfahren funktioniert jetzt wie folgt:
* setze einen Startwert x_0 fest (guter Schätzwert für die Wurzel von z)
* berechne x_1 = x_0 - f(x_0)/f'(x_0)
* allgemeine Form: x_(n+1) = x_n - f(x_n)/f'(x_n)
* wiederhole vorigen Schritt solange abs(x_(n+1) - x_n) > eps, wobei eps ≈ 10^(-14)

Dies kannst du mittels einer while-Schleife realisieren.

Wenn du ein besseres Ergebnis möchtest, dann kannst du für
f(x) = 1-z/x^2
bzw.
f'(x) = 2z/x^3
verwenden.

Das hat den Vorteil, dass du nach ein paar Umformungen auf die Gestalt
x_(n+1) = x_n/2 * (3 - (x_n^2)/z)
kommst und das du nur zu beginn des Verfahrens den Kehrwert von z berechnen musst und das Verfahren dadurch divisionsfrei wird.
 
Zuletzt bearbeitet:
dass ich ja zu doof für den Studiengang sei - was kann ich dafür wenn bestimmte Begriffe in der 3. Vorlesung des 1. Semester noch nicht aufgetaucht sind?? Es is ne Anfängervorlesung die aber iwie nicht so ganz für Anfänger konzipiert ist...
Diese harte Kritik der Anderen hier habe ich auch nicht verstanden und sie ist auch vollkommen unangebracht. Ich hab dipl info studiert und kann daher aus Erfahrung sagen, dass die Wirtschaftsinformatiker eben gerade die theoretische Informatik idR nicht besuchen, wo solche Begriffe erklärt werden. Stattdessen besuchen sie "praktische informatik" um echt programmieren zu lernen - da fehlt es dann halt einfach mal an solchen theoretischen Grundlagen.
Ich versteh auch nicht, wieso man jemanden so runter machen muss... jeder hat mal klein angefangen.

Wenn du deine Lösung noch verbessern willst kannst du sie hier natürlich wieder posten und dir wird sicherlich jemand helfen zumindest die wichtigen Dinge zu verstehen.
 
Das hat nichts mit harter Kritik zu tun.

Jedem mit fortgeschrittenen Programmierkenntnissen dürfte nach Durchsicht des in Beitrag #1 geposteten Codes klar sein, dass der TE selbst einfachste Grundlagen der Programmierung nicht beherrscht. Von einem erkannbaren Algorithmus oder strukturierter Programmierung ganz zu schweigen.

In Anbetracht dieser massiven Schwächen darf man doch an einigen Punkten in der Ausbildung des TEs zweifeln.
 
Danke dir nullPtr, ich werde mich in kürze dransetzen und das lesen =)
Und kuddlmuddl hat recht, ich habe leider nur eine praktische Vorlesung, über eine Vorlesung die sich rein mit Theorie befasst wäre ich dankbar... wird uns aber leider nicht angeboten. Gerade die in meinem Kurs, die so wie ich blutige Anfänger sind - würden ein Modul zu beginn des Studiums, das sich rein mit Theorie zur Programmierung beschäftigt, wohl sehr begrüßen.
 
Zurück
Oben