Intervallmittelpunkt berechnen



  • Hallo,

    ich bin gerade aus Klausurvorbereitungszwecken dabei einige Programmierübungen noch einmal durchzuarbeiten.
    Nun habe ich einen Hänger bei der 5. Übung.
    Bin in C leider nicht so der Oberguru und

    Hier mal die Aufgabenstellung (ist leider einiges, aber wenn ich was weglasse wird nicht ersichtlich was verlangt wird):

    Gegeben ist eine monoton wachsende Funktion f(x) in einem Intervall [a,b] mit f(a) < 0 und f(b) > 0.
    Die Nullstelle im Intervall [a,b] lässt sich durch Intervallschachtelung nach folgendem Algorithmus
    bestimmen:
    1. Berechne den Intervallmittelpunkt m := (a + b) / 2.
    2. Falls f(m) > 0, dann betrachte [a,m] (die untere Hälfte des betrachteten Intervalls) als das
    nächste zu bearbeitende Intervall, andernfalls das Intervall [m,b] (die obere Hälfte des betrachteten
    Intervalls).
    3. Wiederhole die Schritte 1. und 2. solange, bis |f(m)| genügend klein ist, d.h. kleiner als eine vorgegebene Konstante Epsilon ist.
    Schreiben Sie ein Programm für den oben beschriebenen Algorithmus, wobei die Werte von a und b Eingabedaten sind und Epsilon eine symbolische Konstante ist. Strukturieren Sie dieses Programm in folgender Form:
    · Schreiben Sie eine reellwertige Funktion f(x), die ihnen als Ergebnis den Wert der (mathematischen) Funktion f an der Stelle x liefert. Für die Funktion wählen Sie: f(x) = x2 - 5.
    · Schreiben Sie eine weitere Funktion nullstelle mit den Parametern a, b (den Intervallgrenzen), die die gewünschte Nullstelle nachdem o.a. Algorithmus berechnet. Verwenden Sie die Funktion f(x) zur Berechnung der verschiedenen Funktionswerte!
    Wählen Sie für Epsilon zunächst den Wert 0.01.

    Also ich denke, dass mit Punkt 3 ein rekursiver Aufruf gemeint ist.
    Und nun mein Code:

    #include <stdio.h>
    
    int a, b;
    int epsilon = 0.01;
    int m = (a + b) / 2;
    
    int main (void)
    {
    	printf("Bitte geben Sie das obere Intervall an: \n");
    	scanf("%d", &a);
    	printf("Bitte geben Sie das untere Intervall an: \n");
    	scanf("%d", &b);
    
    	int funktion(int a, int b);
    
    	int nullstelle(int a, int b);
    
    	printf("m hat den Wert: %d\n", &m);
    }
    
    int funktion (int a, int b)
    {
    	y = (x * x) - 5;
    
    	return y;
    }
    
    int nullstelle (int a, int b)
    {
    	if (funktion(m)>0)
    		do {
    			nullstelle(a, m)
    		} while (funktion(m) >= epsilon);
    	else
    		do {
    			nullstelle(m, b)
    		} while (funktion(m) >= epsilon);
    
    	return m;
    }
    

    Ich fange mal mit den Problemen an, die ich erkenne.
    Ersichtlich ist, dass in der Funktion funktion die Variablen x und y nicht definiert sind. Allerdings weiß ich auch nicht genau welche Werte ich da nehmen/übergeben muss. Die Parameter hab ich am Anfang reingeschrieben, die sind aber Quatsch, da es ja obere und untere Grenze sind. Die Funktion weiß damit ja gar nichts anzufangen. Steig aber nicht ganz dahinter wie ich das schreiben muss um das gewünschte Ergebnis zu erzielen.

    Die Funktion nullstelle hab ich dann mal so geschrieben wie es mir logisch erscheint, jedoch sind auch hier die gewählten Variablen/Parameter nicht korrekt. Da ich die von vorher nicht kenne weiß ich auch nicht was hier hin soll.

    Hab ich das Problem nun von vorne herein falsch angegangen oder ist meine Lösung teils logisch/korrekt nur nicht in korrektem C geschrieben?
    Würdet mir sehr helfen, wenn ihr hier und da nen Tipp für mich hättet.



  • Atticus86 schrieb:

    int funktion (int a, int b)
    {
    y = (x * x) - 5;

    return y;
    }

    Du meinst f(int x), oder?



  • Atticus86 schrieb:

    Bin in C leider nicht so der Oberguru

    Bei dem Code bleibt leider nur das erste Zeichen vom Oberguru, tut mir leid.

    Das m solltest du mal in der Funktion nullstelle berechnen.

    Und ganz sicher brauchst du keine int Variablen.

    Such doch mal hier im Forum nach Nullstelle. Da findet sich schon was.



  • @LOLAlter: Wie meinst du das?

    @DirkB: Mit dem ersten Satz kann ich auch hier nix anfangen.
    Ich hatte im auch zuerst dadrin stehen, aber dann wird es ja in der main nicht mehr erkannt.
    Wenn ich die "int's" lösche meckert Visual Studio rum und gibt nur noch Fehlermeldungen aus.

    Ich schau mal hier nach "Nullstelle". Danke


  • Mod

    Atticus86 schrieb:

    @LOLAlter: Wie meinst du das?

    Deine Funktion funktion hat von der Logik her nur ein Argument und vom Code her heißt dieses x, der Funktionskopf sagt aber zwei Argumente mit Namen a und b.

    @DirkB: Mit dem ersten Satz kann ich auch hier nix anfangen.

    Er meint, dass dein Code so schlecht ist, dass man nur "O" sagen kann. Es ist fast alles komplett falsch. Ich empfehle noch einmal ganz dringend Grundlagen anzusehen, du bist mit der Aufgabe weit überfordert. Dir fehlt Wissen zu Funktionen und Variablen.



  • Atticus86 schrieb:

    Wenn ich die "int's" lösche meckert Visual Studio rum und gibt nur noch Fehlermeldungen aus.

    😡
    Ich habe nicht gesagt, dass du die int löschen sollst.
    int ist ein Variablentyp für Ganze Zahlen. Nix mit Komma.
    Da wird es Schwierig ein Epsilon von 0.01 zu bekommen.

    SeppJ schrieb:

    Er meint, dass dein Code so schlecht ist, dass man nur "O" sagen kann. Es ist fast alles komplett falsch.

    Nach dem zweiten Post bin ich noch mehr der Meinung, dass das 'O' die Bedeutung bei Telefonnummern hat oder wie bei Hawaii Five-O



  • Ich gebe mal einen Anstoß:

    double funktion (double x)
    {
        return (x * x) - 5;
    }
    
    double nullstelle (double a, double b)
    {
    #define EPSILON 0.01
    hier solltest du weitermachen, u.g. ist so nämlich falsch
    /*
        if (funktion(m)>0)
            do {
                nullstelle(a, m)
            } while (funktion(m) >= epsilon);
        else
            do {
                nullstelle(m, b)
            } while (funktion(m) >= epsilon);
    
        return m;*/
    }
    
    int main (void)
    {
      double a,b;
        printf("Bitte geben Sie das obere Intervall an: \n");
        scanf("%lf", &a);
        printf("Bitte geben Sie das untere Intervall an: \n");
        scanf("%lf", &b);
    
        printf("Nullstelle bei: %f\n", nullstelle(a,b) );
      return 0;
    }
    


  • [quote="DirkB"]

    Atticus86 schrieb:

    Wenn ich die "int's" lösche meckert Visual Studio rum und gibt nur noch Fehlermeldungen aus.

    😡
    Ich habe nicht gesagt, dass du die int löschen sollst.
    int ist ein Variablentyp für Ganze Zahlen. Nix mit Komma.
    Da wird es Schwierig ein Epsilon von 0.01 zu bekommen.
    quote]

    Autsch, jetzt seh ichs auch. Das war ja saudumm. Das hab eigentlich sogar ich gewusst. 😉

    @Wutz: Danke für den Code. Hoffe damit weiterzukommen.



  • definiere eine Fiktion die zu jeden x wert ein y wert liefert

    [code]
    double f(double x)
    {
       return 2*x-5;
    }
    [/code]
    

    um die Nullstelle zu finden gebe einen Bereich(a bis b) vor in die sie liegen muss.
    wenn f(a)<0 und f(b)>0 oder f(a)>0 und f(b)<0 liegt die Nullstelle zwischen a und b.

    jetzt halbiere den Bereich m=(a+b)/2

    die Nullstelle liegt entweder vor oder nach m! somit bekommst du einen neuen Bereich in dem die Nullstelle liegen muss. (a bis m) wenn m>0 oder (m bis b) wenn m<0. du wiederholst den Vorgang bis der m^2 kleiner Epsilon ist.

    [code]
    
        double a=-100;
        double b= 100;
        double Epsilon=0.01;
        double m;
        do
        {
           m=(a+b)/2;
           if (f(m)<0)
           {
              a=m;
           }
           if(f(m)>0)
           {
              b=m;
           }
        }while(f(m)*f(m)>Epsilon);
    
        return m;
    }
    
    [/code]
    


  • hier noch ein paar Änderungen

    #include <iostream>
    #include <stdio.h>
    
    double grade(double x)
    {
       return -2*x-5.387;
    }
    
    double parabel(double x)
    {
       return x*x-5.381;
    }
    
    double nullstelle(double a,double b,double Epsilon,double (*f)(double)) //übergebe eines Funktionspointers
    {
        double m;
        do
        {
           m=(b-a)/2+a;
           if (f(m)*f(a)<0)   //die Nullstelle liegt in dem bereich
           {                  //in dem ein Vorzeichenwechsel statt findet
              b=m;            //also wenn a<0 und m>0 oder umgekehrt.
           }                  //wenn dem so ist, ist a*m < 0
           if(f(m)*f(b)<0)
           {
              a=m;
           }
        }while(f(m)*f(m)>Epsilon*Epsilon);
    return m;
    }
    
    int main()
    {
        printf("%f\n",nullstelle(-10,10,0.00001,grade));
        printf("%f\n",nullstelle(-10,10,0.0001,parabel));
    }
    

Anmelden zum Antworten