-
29.10.11 12:15 #1
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.
-
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ß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, ...?
-
29.10.11 14:45 #3
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
-
T-Sinus 154 data II Wireless-LAN Problem...
Von Prophet05 im Forum Linux & UnixAntworten: 24Letzter Beitrag: 27.05.06, 14:47 -
Problem mit T-Sinus 111 card
Von zeb313 im Forum NetzwerkeAntworten: 0Letzter Beitrag: 17.03.06, 14:06 -
Problem mit WLAN D-Link DWL-G520+ und T Sinus 1054 DSL unter Suse 9.3 Pro
Von Moppel1306 im Forum Linux & UnixAntworten: 13Letzter Beitrag: 21.06.05, 11:07 -
t-sinus 111 data und mandrake 10.1 problem
Von fuzzyblink im Forum Linux & UnixAntworten: 0Letzter Beitrag: 24.02.05, 15:14 -
WLAN Problem - Sinus Data 111
Von alexanderneipp im Forum NetzwerkeAntworten: 0Letzter Beitrag: 08.11.03, 19:38



1Danke

Zitieren

Login






