Programmcode verbessern Wurzel Berechnung
-
Guten Tag,
wir (2 Personen) müssen das folgende Programm zur Benotung abgeben. Wir haben das nach stundenlanger arbeit endlich zum laufen gebracht, also es funktioniert perfekt jedoch wurde uns gesagt das es so wie es zur zeit steht aufjedenfall punktabzüge geben würde, aufgrund der vielen und unübersichtlichen if schleifen.
Könnte jemand der Ahnung von dem Stoff hat mal rüber schauen und paa Verbesserungen durchführen? Es wäre sehr nett.
Code:
#include <iostream> using namespace std; double wurzel(double a, double Xn); int main () { double a, Xn=1.0, d, diff, ergebnis; cout << "Wurzel aus: "; cin >> a; ergebnis = wurzel(a,Xn); cout <<"Ergebnis ist: "<< ergebnis<< endl; system ("PAUSE"); return 0; } double wurzel(double a, double Xn){ double d=0.000001, diff, Yn; Yn = 0.5 *(Xn + a/Xn); diff= Xn - Yn; if (diff<0) diff=diff * (-1); if (a >= 0){ if (diff<d){ return Yn; } else{ return wurzel(a, Yn); } } else { cout << "Berechnung von negativen Zahlen nicht moeglich!"<< endl ; } }Wir bedanken uns im Voraus.
Mit freundlichen Grüßen
memoli
-
ahja es handelt sich hierbei um http://de.wikipedia.org/wiki/Newton-Verfahren#Berechnung_der_Quadratwurzel
Newton Verfahren - Berechnung der Quadratwurzel
-
double wurzel(double d) { const double diff = 0.00001; double val = 1.0; do val = 0.5 * (val + d / val); while (fabsf(val * val - d) > diff); }
-
wow schnelle antwort danke erstmal

habs gerade versucht, aber funktioniert irgendwie nicht bei mir. evtl hab ichs falsch eingebaut
koenttest du das in dem programm mal kurz intergrieren?
-
Ich würde an eurer Stelle bei der eigenen Lösung bleiben. Hier wisst ihr das es geht und warum es geht. Falls sich der Pädagoge an eurem Algorythmus stören sollte, hat er sich wohl im Beruf geirrt. Weil es gibt nicht nur die eine richtige Lösung.
Was ihr aber machen solltet ist auf eine gescheite Formatierung achten und ungenutzte Variablen entfernen (schaut euch noch mal main an).
Bei der Gelegenheit ist es auch ratsam, auf ordentliche Variablen-Namen zu achten. Namen wie a sind nicht sehr aussagekräftig.
Schön ist es naturlich auch wenn ihr den Code kommentiert, insbesondere um Nachzuvollziehen wie die Wurzel entsteht.
Zum Schluß haben Aufrufe wie System("Pause") in einem Programm eigentlich nix verloren. Zum Testen ja, vor der Abgabe aber evtl. rausmachen.
-
Also mein erstes Wurzelprogramm sah ungefähr so aus.
#include <iostream> using namespace std; double berechne(double x){ double wurzel=0.00000001; while(wurzel*wurzel <=x){ wurzel+=0.0000001; } return wurzel; } main(){ double x; double wurzel; do{ cout << "Wurzel aus : "; cin >> x; }while(x < 0); wurzel=berechne(x); cout << "Die Wurzel aus " << x << " ist " << wurzel; }Es ist zwar vom Aufbau her sehr primitiv und hat je nach größe der zu berechnenden Zahl eine lange Berechnungszeit aber der Code ist relativ leicht nachzuvollziehen. Habe mich aber dann nicht mehr beschäftigt.
Also nur mal eine Lösung wie man es auch hätte machen könnte
-
Jedoch könnte man die Genauigkeit etwas reduziren dann läufts was schneller.
double berechne(double x){ double wurzel=0.0001; while(wurzel*wurzel <=x){ wurzel+=0.0001; } return wurzel; }
-
dann könnte man noch ne konstante für die zahl nehmen und ein schleifendurchlauf mehr is auch nich so das problem:
Andyman schrieb:
const double delta = 0.0001; double berechne(double x){ double wurzel = 0; while(wurzel*wurzel <= x){ wurzel += delta; } return wurzel; }@memolibey:
an deiner stelle würde ich das ganze mal anständig einrücken und schon kann man es lesen ^^ so würd ich auch pkt abziehen...bb
-
Andyman schrieb:
Jedoch könnte man die Genauigkeit etwas reduziren dann läufts was schneller.
Oder halt doch das Newton-Verfahren benutzen. Das konvergiert so schnell, dass man da durchaus auf die volle Genauigkeit gehen kann, ohne dass es weh tut. So in etwa:
// Wurzel aus a, Newton-Iteration double wurzel(double a) { if (a == 0) return 0; // muss sein, weil die Wurzel bei 0 nicht differenzierbar ist double x, xn = 1; do { x = xn; xn = 0.5*(x + a/x); } while (x != xn); return x; }Für Zahlen in "normalen" Bereichen dürfte das ganz gut funktionieren, die Wurzel aus 10^300 zu ziehen dauert aber entsprechend lang, reale Implementierungen sollten da vorher noch etwas Arbeit investieren, um einen guten Startpunkt zu finden (z.B. den Exponent halbieren, also bei A*10^300 mit A*10^150 anfangen)
Edit: Über die Robustheit der Abbruchbedingung müsste man sich auch noch Gedanken machen