Nullstellenberechnung durch Intervallhalbierung
-
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?
-
Erste Intervallhalbierung:
(1 + 4) / 2 = 2,5!
Diese 2,5 musst du nun wieder in die Gleich
x * x -2 einsetzen, um zu testen ob ein Vorzeichen-
wechsel statt fand.2,5 * 2,5 -2 = 4,25
-
Lyb schrieb:
Diese 2,5 musst du nun wieder in die Gleich
x * x -2 einsetzen, um zu testen ob ein Vorzeichen-
wechsel statt fand.2,5 * 2,5 -2 = 4,25
Das ist mir alles klar.
Nur in deinem Programm brechnest du das nicht!
Du musst doch prüfen ob der Vorzeichenwechsel im Bereich a,m oder m,b stattfindet.
Du berechnest aber nirgends den Funktionswert an der Stelle m.
Dasfvonm = *m * *m -2;
fehlt.
-
Absolut richtig Dirk, ich danke dir!
Aber zusätzlich stimme auch noch die Prüfung im
if-statement nicht:#include <stdio.h> #include <stdlib.h> /************************************************************************/ int bisection(double a, double b, double *m) { int iterations = 0; double fvonx1 = 0; double fvonx2 = 0; double fvonm = 0; while (iterations < 100) { fvonx1 = a * a -2; fvonx2 = b * b -2; *m = (a + b) / 2; fvonm = *m * *m -2; if (fvonm < fvonx2 && fvonm > 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); } /************************************************************************/
So funktioniert der Code
Also zumindest die Berechnung, das drum rum macht noch nicht
viel Sinn, weil er jedes mal abbrechen würde wegen zu vieler
IterationenDanke!
-
Da Abbruchkriterium aus deiner ersten Version war auch besser.
while (b - a > 1.0e-10)
Mach evtl. erstmal 1.0e-5.
-
Bei dieser Bedingung geht er kein einziges mal in die Schleife rein.
-
Es geht: http://codepad.org/51EbPkks
Beim letzten mal waren a und b auch Zeiger.