Problem mit Taschenrechner der cmath nutzt
-
Die Winkelfunktionen der C-Bibliothek rechnen im Bogenmaß (d.h. 180° ≡ Pi)
-
Die trigonometrischen Funktionen arbeiten hier mit Bogenmaß. Du mußt dein Gradmaß also erst umrechnen (*PI/180).
[edit]Das war aber spät.
[edit]
-
und warum ist das nicht richtig:
... //Weil die Winkelfunktionen im Bogenmaß rechnen muss bei den trigonometrischen Funktionen mit PI/180 multipliziert werden double pi=3.1415; case 8: c=cos(a)*(pi/180); break;Und ich habe vor einigen Tagen was von M_PI gelesen um einen konstanten Wert für PI zu verwenden. Könnt ihr mir das auch eben erklären?
Soll ich dann doublepi=M_PIschreiben?
-
Erstens ist 3.1415 nur eine sehr grobe Näherung für Pi (besser ist M_PI, wenn der Compiler es kennt, oder 4*atan(1)). Und zweitens mußt du das richtig klammern:
c = cos(a*pi/180);
-
case 8: c=cos(a*M_PI/180); break;Ist aber auch !=0
-
Was liefert er sonst? (und welchen Eingabewert verwendest du?)
-
CStoll schrieb:
Was liefert er sonst? (und welchen Eingabewert verwendest du?)
Ich verwende 90, wovon halt der Cosinus 0 ist. Aber mein Programm spuckt aus: 6,12303e-017
Hier nochmal meiner ganzes Programm. Die Anderen Auswahlmöglichkeiten habe ich mit Kommentarfunktion unterdrückt, weil erstmal eine Funktion laufen soll:#include <iostream> #include <conio.h> #include <cmath> using namespace std; int main(void) { int wahl; double a; double b; double c; //Weil die Winkelfunktionen im Bogenmaß rechnen muss bei den trigonometrischen Funktionen mit PI/180 multipliziert werden cout << "Bitte waehlen Sie die gewuenschte Operation!" << endl; cout << "1. Addition" << endl << "2. Subtraktion" << endl << "3. Multiplikation" << endl << "4. Division" << endl << "5. Potenzierung" << endl << "6. Quadrat-Wurzel ziehen" << endl << "7. Sinus" << endl << "8. Cosinus" << endl << "9. Tangens" << endl << "10. Arcussinus" << endl << "11. Arcuscosinus" << endl << "12. Arcustangens" << endl; cout << endl << "Geben Sie die Zahl fuer diese Operation bitte jetzt ein: "; cin >> wahl; if(wahl<=4) { cout << "Bitte geben Sie die erste Zahl ein: "; cin >> a; cout << endl; cout << "Bitte geben Sie die zweite Zahl ein: "; cin >> b; } else if (wahl==5) { cout << "Bitte geben Sie die Basis ein: "; cin >> a; cout << "Bitte geben Sie den Exponenten ein: "; cin >> b; } else { cout << "Bitte geben Sie die Zahl ein: "; cin >> a; } switch (wahl) { /* case 1: c=a+b; break; case 2: c=a-b; break; case 3: c=a*b; break; case 4: c=a/b; break; case 5: c=pow(a, b); break; case 6: c=sqrt(a); break; case 7: c=sin(a)*(pi/180); break;*/ case 8: c=cos(a*M_PI/180); break; /*case 9: c=tan(a)*(pi/180); break; case 10: c=asin(a)*(pi/180); break; case 11: c=acos(a)*(pi/180); break; case 12: c=atan(a)*(pi/180); break; */ } cout << endl << "Das Ergebnis der Operation ist: " << c; getch(); return 0; }
-
Das sind bei der Berechnungen auftretende Ungenauigkeiten.
6*10^-17 ist doch praktisch gleich 0.
Wenn du Ausgaben, wie dein Taschenrechner sie erzeugt, haben willst,
mußt du schon formatierte Ausgaben benutzen.
-
wenn ich als noob auch mal meinen senf dazugeben darf: 6,12303e-017 ist doch eine sher kleine abweichung von 0, also könnte es schon an einem ungenauen pi-wert liegen, dann könnte mann die ergebnisse doch einfach runden, auf z.b. 3 dezimalstellen, dann kommt bei 90 ja auch 0.000 raus
edit: shit schon wieder zu spät

-
Javaner schrieb:
Wenn du Ausgaben, wie dein Taschenrechner sie erzeugt, haben willst,
mußt du schon formatierte Ausgaben benutzen.Da hab ich noch nichts von gehört. Ich dachte double hat nur eine begrenzte Anzahl von Fließkommastellen und gibt dann einfach 0 aus. Hmmm. Wie mache ich denn eine formatierte Ausgabe?
-
Das ist nicht richtig. Double hat als Fließkommazahl keinen "festen Wertebereich" oder "feste Anzahl Stellen". Strenggenommen.
Ein Fließkommawert wird als Mantisse + Exponent gespeichert. Bildlich ausgedrückt eine Ziffernfolge (deren Länge die tatsächliche Stellenzahl angibt) und eine Angabe wo in dieser Ziffernfolge das Komma steht.
Mal angenommen der Exponent hätte die Basis 10 und die Mantisse 5 Stellen, dann wäre "01234+000" die Zahl 1234. "01234-010" wäre 0,0000001234, "01234+003" wäre 1234000. Das ist wichtig, weil die Genauigkeit "weiter rechts" abnimmt, je größer die Zahl nach links driftet. In diesem Modell wären 10000,1 und 10000,2 schon identisch (beide "10000+000").
Alles völlig unwissenschaftlich und anschaulich, bitteschön

Korrekturen willkommen
-
Ich habe mir nun anderweitig geholfen. Ist vielleicht nicht die goldene Lösung, erfüllt aber seinen Zweck und ist eine mir bekannte Variante

cout << endl << "Das Ergebnis der Operation ist: " << c; cout << endl << fixed << setprecision(2) << "Auf zwei Stellen gerundet: " << c;
-
LordJaxom schrieb:
Das ist nicht richtig. Double hat als Fließkommazahl keinen "festen Wertebereich" oder "feste Anzahl Stellen". Strenggenommen.
Strenggenommen hat ein double wohl einen festen Wertebereich. Daten typen haben immer einen festen Wertebereich. Daß dieser Wertebereich allerdings im Falle von double nicht durch eine feste Anzahl Stellen festgelegt ist, ist natürlich richtig.
-
Ja, mir ist auch aufgefallen dass meine Beschreibung auch genau auf "feste Anzahl Stellen" passt, nur mit variablem Komma

Aber ihr wisst ja wie's gemeint ist...
-
t1m0n schrieb:
Ich habe mir nun anderweitig geholfen. Ist vielleicht nicht die goldene Lösung, erfüllt aber seinen Zweck und ist eine mir bekannte Variante

Na bitte, er hat doch selber herausgefunden, wie die "formatierte Ausgabe" klappt

-
CStoll schrieb:
t1m0n schrieb:
Ich habe mir nun anderweitig geholfen. Ist vielleicht nicht die goldene Lösung, erfüllt aber seinen Zweck und ist eine mir bekannte Variante

Na bitte, er hat doch selber herausgefunden, wie die "formatierte Ausgabe" klappt

Ist das genau die Variante die ihr meintet??? Wenn ja hab ich auch mal einen blinden Treffer ohne Google (nur mit Buch) gelandet

-
Das ist eine mögliche Variante - je nach Bedarf könntest du noch an der Genauigkeit der Ausgabe (setprecision()) schrauben oder doch auf wissenschaftliche Darstellung wechseln (dann müsstest du dir eine eigene Genauigkeitsgrenze definieren und alles darunter auf 0 setzen: "if(c<epsilon) c=0;")
-
CStoll schrieb:
"if(c<epsilon) c=0;")
Was bedeutet das? Hab öfters schon von EPSILON gehört aber nichts genaueres in Tutorials erfahren. Kannst das mal erläutern oder einen Link geben?
-
"epsilon" mußt du selber definieren als eine recht kleine Zahl - die obige Anweisung setzt alles, was unter dem vorgegebenen Wert liegt, auf 0 (OK, in manchen Situationen mußt du tatsächlich mit so kleinen Werten arbeiten, aber das ist selten).
-
Bezüglich epsilon noch zwei Links zur weiteren Aufklärung.
http://de.wikipedia.org/wiki/Epsilon (Bereich Mathematik)
http://de.wikipedia.org/wiki/Epsilontik (Epsilontik)