Nullstellenberechnung durch Intervallhalbierung
-
Hallo, ich komme gerade nicht weiter bei oben genannten Thema.
Und zwar wird immer 0.0000 als Ergebnis ausgegeben, das ist allerdings
bei x*x-2 nicht korrekt, da müsste die Wurzel von 2 rauskommen.Habe ich einen Fehler im Code?
#include <stdio.h> #include <stdlib.h> /************************************************************************/ int bisection(double *a, double *b, double *m) { int iterations = 0; while (b - a > 1.0e-10) { *m = (*a + *b) / 2; if ((*a * *a - 2) * (*m * *m - 2) < 0) { *b = *m; } else { *a = *m; } iterations++; if (iterations >= 100) { return 1; } } return 0; } /************************************************************************/ int main(void) { double a = 2; double b = 3; double m = 0; if (bisection(&a, &b, &m) == 1) { printf("Die Berechnung wurde nach zu vielen Durchläufen beendet!\n"); } else { printf("Die Nullstelle der Funktione lautet: %f\n", m); } system("PAUSE"); /* fertig! */ exit(0); }
-
Geh den Code mal im Debugger durch, dann solltest du den Fehler sofort sehen und lernst zudem noch, mit einem Debugger zu arbeiten, was eines der wichtigsten Werkzeuge in der Programmierung ist.
Der Fehler hier ist recht schwer durch Lesen des Codes zu finden (hab's zuerst auch nicht gesehen), daher ist es gut, weitere Hilfsmittel zu beherrschen.
-
Wenn ich das Programm also beispielsweise in Visual Studios lade,
gibt es dort einen Debug Modus. Also muss an die Stellen die ich Teste
einen Ausgabepunkt setzen oder einen Haltepunkt und dann mit dem Debugger
das Programm durchlaufen lassen.So korrekt?
Wenn ja, findet er nix ^^
-
Du setzt einen Haltepunkt am Anfang der Funktion. Wenn der Programmfluss dort ankommt, wird der Debugger das Programm unterbrechen. Dann gehst du von dort aus schrittweise weiter. Ich kenne den Debugger von VS nicht, aber so eine Funktionalität hat der garantiert.
Und dann findet nicht der Debugger den Fehler, sondern du. Der Debugger hilft dir, den tatsächlichen Programmablauf zu verstehen, so dass du mit dem vergleichen kannst, was du eigentlich möchtest (es sollte offensichtlich sein, was da falsch läuft), das Denken kann er dir nicht abnehmen.
-
Das denke ich kleine offensichtliche Problem wird ein großes Problem, wenn man sich erstmal in die Funktionen eines Debuggers einarbeiten muss.
Den Haltepunkt habe ich gefunden und eingebaut, mit F11 kann man dann Schritt für Schritt von Zeile zu Zeile gehen, ich verstehe allerdings die Ausgaben nicht, irgendwelche Hexadezimalcodes.
-
Es gibt im Debugger auch ein Fenster in dem die Variablenwert drin stehen, bzw. wo du dir die anzeigen lassen kannst.
-
Jap okay, hab ich gefunden, nur überspringt er die entscheidenden Stellen.
Ich habe nun einen Haltepunkt vor meine Funktion gepackt.
Starte den Debugger.
Gehe mit F11 Schritt für Schritt durch, das sind anscheinend aber nur drei Schritte. Er macht Drei Ausgaben.
Wert von a
Wert von b
Wert von mdann geht er Schritt weiter
Wert von iterationdann den nächsten Schritt
Wert von iterationUnd dann ist Ende
-
Fällt dir an den Werten von a,b und m etwas auf?
-
Hmmm...Neee, alles so wie es sein soll.
a = 2;
b = 3;
m = 0;EDIT: Ahhhh, moment.....
Ist der Fehler hier? while (b - a > 1.0e-10)
Er geht garnicht erst in die Schleife oder?
-
In der Zeile müsste der Compiler eigentlich eine Warnung geben.
Warum übergibst du überhaupt a und b als Zeiger?
-
Das ist im Laufe der Fehlersuche so entstanden,
Ist natürlich nicht nötigJetzt verstehe ich auch den Debugger, warum er
nach drei Schritten schon fertig war => Er hat
die While Schleife übersprungen, weil die Bedingung
nicht erfüllt war.Danke, nicht nur beim Fehler geholfen sondern auch
zur Nutzung des Debuggers animiertIst dennoch nicht fertig, muss ich nochmal drüber,
denn das Programm funzt trotzdem nicht richtig^^
-
Okay, bekomme das Programm nicht korrekt hin, das hat aber keine Programmiertechnischen Gründe, sondern Mathematische....
Haben wir einen mit guten Mathe-Kenntnissen hier?Ich weiß nicht genau wann ich in welchem Intervall suchen muss.
#include <stdio.h> #include <stdlib.h> /************************************************************************/ int bisection(double a, double b, double *m) { int iterations = 0; double fvonx1 = 0; double fvonx2 = 0; while (iterations < 100) { fvonx1 = a * a -2; fvonx2 = b * b -2; *m = (a + b) / 2; if (fvonx1 * fvonx2 < 0) { b = *m; } else { a = *m; } iterations++; if (iterations >= 100) { return 1; } } return 0; } /************************************************************************/ int main(void) { double a = 1; double b = 4; double m = 0; if (bisection(a, b, &m) == 1) { printf("Die Berechnung wurde nach zu vielen Durchläufen beendet!\n"); } else { printf("Die Nullstelle der Funktione lautet: %f\n", m); } system("PAUSE"); /* fertig! */ exit(0); } /************************************************************************/
Das ist der Code und ich suche zuerst im Intervall von 1 und 4
mit der Funktion x*x-2 (Da müsste bei ca. 1,41 eine Nullstelle sein)Erster Durchlauf:
a = 1
b = 4f(1) = -1
f(4) = 14Annäherung = (1 + 4)/2 = 2,5
(-1 *14) < 0 = wahr also wird b zu 2,5Zweiter Durachlauf:
a = 1
b = 2,5f(1) = -1
f(2,5) = 4,25Annäherung (1 + 2,5)/2 = 1,75
(-1 * 4,25) < 0 = wahr also wird b zu 1,75Dritter Durchlauf: (HIER PASSTS NICHT MEHR)
a = 1
b = 1,75(f1) = -1
f(1,75) = 1,0625Jetzt sind wir nicht mehr im Intervall indem sich
die Nullstelle befindet. So kann die 1,41 nicht gefunden
werden.
-
Lyb schrieb:
Annäherung = (1 + 4)/2 = 2,5
(-1 *14) < 0 = wahr also wird b zu 2,5Woher weißt du, das b zu m (2,5) werden muss und nicht a?
-
Weil -1 kleiner als 14 ist
und als ergebnis 2,25 rauskam.
Zwischen 14 und 2,25 fand kein Vorzeichenwechsel statt,
daher wird die 4 durch 2,25 ersetzt. Jetzt wird der Bereich von
1 und 2,25 untersucht.
-
Lyb schrieb:
Zwischen 14 und 2.25 fand kein Vorzeichenwechsel statt,
Wo überprüfst du das denn (ich meine die 2.25)? Du hast nur die Werte 1, 4 und 2,5 sowie -1 und 14. Wo kommt die 2.25 her?
-
Ach quatsch, sorry, meinte nicht 2,25 sondern 2,5.
Also 1 + 4 /2 = 2,5Dann 2,5 * 2,5 -2 gibt 4,25
Das nächste intervall das untersucht wird ist nun 1 und 2,5
weil zwischen 14 und 4,25 kein Vorzeichenwechel statt fand.
So stimmts nun, sorryAber das hatte ich glaub ich schon so unter dem Code-Segment
gepostet
-
Lyb schrieb:
Dann 2,5 * 2,5 -2 gibt 4,25
Wo in deinem Programm berechnest du das?
-
fvonx1 = a * a -2; fvonx2 = b * b -2;
-
Lyb schrieb:
fvonx1 = a * a -2; fvonx2 = b * b -2;
a = 1; b = 4;
Wo berechnest du f(4,25) ?
-
Sorry.
a = 1; b = 4;
Wo berechnest du f(2.5) = 4.25?