tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von sheel
ERLEDIGT
JA
ANTWORTEN
2
ZUGRIFFE
377
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von Atalión
    Atalión Atalión ist offline Mitglied Bronze
    Registriert seit
    Aug 2007
    Ort
    Frankfurt am Main
    Beiträge
    47
    Hi zusammen!

    Ich studiere jetzt im ersten Semester Medieninformatik und wir müssen für das Fach "Einführung in die Programmierung" verschiedene Übungen bearbeiten. Eine Übung ist, den Sinus eines Winkels mit der Formel sin x = x – x^3/3! + x^5/5! - x^7/7! + ... zu berechnen (in C). Die Rechnung soll abgebrochen werden, "wenn der Wert des nächsten Ausdrucks kleiner als 10^-5 wird". Wär schön gewesen, wenn der Prof dazugeschrieben hätte, welcher Ausdruck genau gemeint ist. Ich bin jetzt vom Quotienten x^3/3! etc. ausgegangen.

    Ich habe jetzt eine Funktion geschrieben, die soweit eigentlich funkioniert, allerdings nur für Winkel von 1° bis ca. 34°.. ab 41° wird das Ergebnis dann richtig ungenau und schießt exponentiell in die Höhe.

    Entweder habe ich irgendwo doch einen Logikfehler in der Rechnung oder ich überseh etwas anderes. Wäre cool, wenn mir jemand einen Hinweis geben könnte, in welche Richtung ich da denken muss, was ich verändern müsste (braucht also keine komplette Lösung des Problems sein, ein wenig muss ich ja auch selbst denken ).

    Hier noch mein Quellcode:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    
    #include <stdio.h>
    #include <conio.h>
    #include <math.h> // für die Sinus-Berechnung
     
    int main(void) {
        
        int i, j, k;
        float sinuswink;
        long double rechnung, fak, xwink, final, pot, quot, testq=1;
     
        printf("BERECHNEN DES SINUS VOM WINKEL x");
        
        do {
            printf("\n\nDieses Programm berechnet den Sinus vom Winkel x.\n\nBitte geben Sie einen Winkel ein: ");
     
            scanf_s("%lf",&xwink);
            pot=xwink;
            quot=1;
            rechnung=0;
     
            for(i=3;quot>0.00005||quot<-0.00005;i=i+2) {
     
                // Fakultät
                fak=1;
                for(j=1;j<=i;j++) fak=j*fak;
     
                // Potenz von x
                xwink=pot;
                for(k=1;k<i;k++) xwink=xwink*pot;
     
                // Vorzeichen von quot bestimmen
                if(quot > 0) {
                    quot=xwink/fak;
                    quot=-quot;
                } else {
                    quot=xwink/fak;
                }
     
                rechnung=rechnung+quot;
            }
     
            // Komplette Sinus-Rechnung
            final=pot+rechnung;
     
            // Überprüfung mit Funktion aus math.h
            sinuswink = (float)sin((float)pot);
     
            printf("sin(x) = %.5lf\n\n",final);
            printf("sin(x) = %.5lf\n\n",sinuswink);
     
            printf("\nBeliebige Taste zum Fortfahren druecken. \"n\" beendet das Programm.\n\n");
        
        } while(_getch()!='n');
     
        return(0);
    }

    LG,
    Malte
    Geändert von Atalión (29.10.11 um 12:28 Uhr)
     
    Fantasy-Fans.eu
    Realität war gestern.

  2. #2
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.501
    Hi

    ohne den Code schon genauer angeschaut zu haben:
    Hast du mit dem Debugger/Taschenrechner mal überprüft,
    wo die Rechnungsergebnisse falsch werden?

    Schau mir den Code jetzt selber an...

    edit1:
    Ohne (noch) selbst debuggt zu haben, eine mögliche Fehlerquelle:

    Du berechnest jedes Teilstück von vorne weg, also
    x*x*x*x.../(1*2*3*4...)
    Dabei machst du zuerst Zähler/Nenner einzeln und dividierst erst dann.
    Die Zahlen können dabei schon mal sehr groß werden bzw. viele Kommastellen haben,
    die (vor allem bei den Kommastellen) bei Bedarf ohne Vorwarnung intern einfach weggeschnitten werden,
    wenns zu genau für double wird.
    Da kann schon einiges an Genauigkeit verloren gehen.

    Eventuell besser wäre es, wenn man jedes Teilstück aus dem vorigen berechnet.
    zB. man hat schon A=x^5/5! und will die 7-Stufe.
    Dafür nimmt man einfach A*x/6*x/7

    Ich versuch, ob es so besser wird...sonst Debugger.

    edit2:
    Mein Code, der das Größenproblem noch immer hat, ist unten.

    Aber:
    Du redest von 1, 34 und 41 Grad.
    Meinst du zufällig die "Grad", bei denen der Kreis 360° hat?
    Deine math. Formel will Radiant
    2PI statt 360.

    Wenn man daher die Eingabe vor der Berechnung mod 2PI nimmt
    sollte es mit keiner Zahl Probleme geben.
    Hab es nicht im Code, ist aber bei Bedarf schnell gemacht.

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    #include <stdio.h>
    #include <math.h>
     
    #define PI 3.14159265
     
    double sinus(double rad)
    {
        double ret, teil;
        int i;
     
        ret = 0.0;
        teil = rad;
        i = 1;
     
        while(teil < -0.00001 || teil > 0.00001)
        {
            ret += teil;
     
            teil *= -1.00;
            teil *= rad;
            teil /= (double)(++i);
            teil *= rad;
            teil /= (double)(++i);
        }
     
        return ret;
    }
     
    int main(int argc, char *argv[])
    {
        double x;
     
        while(1)
        {
            scanf("%lf", &x);
            printf("sin(%lf) = %lf\n", x, sinus(x));
        }
     
        return 0;
    }

    Gruß
    Atalión bedankt sich. 
    Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
    Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
    "Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?

  3. #3
    Avatar von Atalión
    Atalión Atalión ist offline Mitglied Bronze
    Registriert seit
    Aug 2007
    Ort
    Frankfurt am Main
    Beiträge
    47
    aaaah, wie doof kann man sein? Rate mal, was in der Aufgabenstellung steht? "Diese Formel gilt für den Winkel x im Bogenmaß." ... ich sollte genauer lesen.

    Vielen Dank, mit dem Bogenmaß funktioniert es super! Und ich werde mal versuchen, deinen Vorschlag umzusetzen, die einzelnen Teile nicht von Anfang an zu berechnen.

    Also, vielen Dank noch einmal. Hast mir sehr weitergeholfen!
     
    Fantasy-Fans.eu
    Realität war gestern.

Ähnliche Themen

  1. T-Sinus 154 data II Wireless-LAN Problem...
    Von Prophet05 im Forum Linux & Unix
    Antworten: 24
    Letzter Beitrag: 27.05.06, 14:47
  2. Problem mit T-Sinus 111 card
    Von zeb313 im Forum Netzwerke
    Antworten: 0
    Letzter Beitrag: 17.03.06, 14:06
  3. Antworten: 13
    Letzter Beitrag: 21.06.05, 11:07
  4. t-sinus 111 data und mandrake 10.1 problem
    Von fuzzyblink im Forum Linux & Unix
    Antworten: 0
    Letzter Beitrag: 24.02.05, 15:14
  5. WLAN Problem - Sinus Data 111
    Von alexanderneipp im Forum Netzwerke
    Antworten: 0
    Letzter Beitrag: 08.11.03, 19:38

Stichworte