Hi Leute, ich habe eine Aufgabe die ich lösen soll und komm nicht ganz weiter: Erstellen Sie ein C-Programm, das eine Gleitpunktzahl in einer Variablen und eine Anzahl von Nachkommastellen in einer anderen Variablen definiert. Das Programm soll nun die erste Zahl auf die angegebenen Anzahl von Nachkommastellen auf- und abgerundet ausgeben. Zusätzlich soll dieses Programm auch noch die Zahl auf die angegebenen Nachkommastellen be- grenzt ausgeben lassen, wobei es die Rundung den intern vorgegebenen Regeln überlässt. Am Ende soll dieses Programm für die eingegebene Zahl noch die deutsche Schreibweise (mit Komma) ausgeben. Mögliche Ausgaben dieses Programms sind: /* * Gleitpunktzahl: 12.345678 * Kommastellen runden: 4 */ Abgerundet: 12.3456 Aufgerundet: 12.3457 Nach Rundungsregeln: 12.3457 In deutscher Schreibweise: 12,3457 Hinweis: Fügen Sie #include <math.h> hinzu. Dann können Sie die Funktionen floor, ceil und modf ver- wenden. Zu floor und ceil lesen Sie unter http://de.wikipedia.org/wiki/Abrundungsfunktion_und_Aufrundungsfunktion , was die beiden Funktionen für Sie berechnen. Die Anweisung nachkomma = modf(zahl,&vorkomma); zerlegt die Zahl zahl in die Teile vor bzw. nach dem Komma und schreibt sie in die Variablen vorkomma bzw. nachkomma. (Das ominöse & vor vorkomma wird später erklärt!) Weiß jemand damit etwas anzufangen???
:
Verschoben durch User
DjangoG schrieb: > Weiß jemand damit etwas anzufangen??? Eigentlich schon. So gut wie alle Schwierigkeiten sind in der Aufgabenstellung angesprochen und Lösungswege dafür aufgezeigt worden. Die Einzelinformationen müssen noch miteinander kombiniert werden und ein Programm dafür geschrieben werden. Das wird vielleicht nicht auf Anhieb alles richtig machen, aber mit ein wenig Geduld und Spucke und dem Verständnis dessen, was die einzelnen angesprochenen Funktionen machen, ist es eigentlich kein Problem diese Aufgabe zu lösen. Das einzige was vielleicht noch erwähnt werden sollte, ist die simple Tatsache, dass man mit geeigneten Multiplikationen mit Vielfachen von 10, ein Komma auch verschieben kann. So wird aus 123.456789 durch Multiplikation mit 10000 die Zahl 1234567.89 in der die ersten 4 ursprünglichen Nachkommastellen jetzt alle vor dem Komma sitzen, was die Anwendung von floor bzw. ceil deutlich erleichtern dürfte, wenn man auf n Kommastellen (in diesem Beispiel wäre n dann 4 gewesen) runden soll (egal ob auf- oder abrunden)
:
Bearbeitet durch User
So hab ich das jetzt mal versucht:
1 | int main(int argc, char** argv) { |
2 | |
3 | double zahl = 12.345678,nachkomma, vorkomma,aufgerundet, abgerundet; |
4 | |
5 | nachkomma = modf(zahl ,&vorkomma); |
6 | |
7 | printf("Nachomma: %lf",nachkomma); |
8 | printf("\nVorkomma: %lf", vorkomma); |
9 | |
10 | nachkomma = nachkomma *10000; |
11 | nachkomma = ceil(nachkomma) / 10000; |
12 | aufgerundet = nachkomma + vorkomma; |
13 | |
14 | |
15 | //printf("Abgerundet: %lf", );
|
16 | printf("Aufgerundet: %.4lf",aufgerundet); |
17 | printf("\nNach Rundungsregel: %.4lf", zahl); |
18 | //printf("\nIn deutscher Schreibweise: %lf,%lf",vorkomma, nachkomma );
|
19 | |
20 | return (EXIT_SUCCESS); |
21 | }
|
Aber wenn ich das jetzt einmal durchgemacht habe, müsste ich ja wieder eine neue Variable für nachkomma definieren oder? Damit ich mit abgerundet weiter machen kann? Ich hab erst vor kurzem mit C angefangen & programmiert habe ich vorher auch noch nie..
:
Bearbeitet durch User
DjangoG schrieb: > Aber wenn ich das jetzt einmal durchgemacht habe, müsste ich ja wieder > eine neue Variable für nachkomma definieren oder? Damit ich mit > abgerundet weiter machen kann? Allerdings zwingt dich niemand, dass du dir den Wert in nachkomma hier
1 | nachkomma = ceil(nachkomma) / 10000; |
2 | aufgerundet = nachkomma + vorkomma; |
zerstörst. Du kannst das ja auch so schreiben ...
1 | aufgerundet = vorkomma + ceil(nachkomma) / 10000; |
... wodurch dir der ursprüngliche Wert in nachkomma erhalten bleibt und für die nächste Rundungsvariante zur Verfügung steht. Man darf durchaus auch komplexere Ausdrücke schreiben und muss nicht immer auf der rechten Seite einer Zuweisung nur einfache Ausdrücke mit lediglich einer einzigen Operation haben.
:
Bearbeitet durch User
Mal schauen, wie lange es dauert, bis du folgenden code schaffst zum laufen zu bringen. Wenn du ihn verstehst, kennst du datentypen. Ungetestet:
1 | void runden(double x,double &abgerundet,double &aufgerundet,double &arithmatisch,int s=2,int base=10){ |
2 | |
3 | long double n=pow(base,s); |
4 | |
5 | abgerundet = (long long)(n*x); // floor(n*x) |
6 | aufgerundet = (n*x-abgerundet==0)?abgerundet:abgerundet+1l; |
7 | arithmatisch = (long long)(n*x+0.500001l); // round(n*x) |
8 | |
9 | abgerundet /= n; |
10 | aufgerundet /= n; |
11 | arithmatisch /= n; |
12 | |
13 | }
|
:
Bearbeitet durch User
Danke für die Hilfe! Wusste nur nicht wie ich das mit dem normalen Komma lösen soll.
1 | int main(int argc, char** argv) { |
2 | |
3 | double zahl = 12.345678,nachkomma, vorkomma,aufgerundet, abgerundet; |
4 | |
5 | nachkomma = modf(zahl ,&vorkomma); |
6 | nachkomma = nachkomma *10000; |
7 | |
8 | abgerundet = vorkomma + floor(nachkomma) / 10000; |
9 | aufgerundet = vorkomma + ceil(nachkomma) / 10000; |
10 | |
11 | |
12 | printf("\nGleitpunktzahl: %lf\n",zahl); |
13 | printf("\nAbgerundet: %.4lf", abgerundet); |
14 | printf("\nAufgerundet: %.4lf",aufgerundet); |
15 | printf("\nNach Rundungsregel: %.4lf", zahl); |
16 | printf("\nIn deutscher Schreibweise: %.0lf,%.0lf\n",vorkomma, nachkomma ); |
17 | |
18 | return (EXIT_SUCCESS); |
19 | }
|
:
Bearbeitet durch User
Test das mal mit 1.0023456789 und achte auf die deutsche Ausgabe. Die Anzahl der Nachkommastellen soll auch variabel sein. Was mit printf geht, kannst du hier nachlesen: http://www.cplusplus.com/reference/cstdio/printf/
Danke für den Tipp. Das funktioniert so nicht, da hast du Recht! Aber ich weiß ehrlich gesagt auch nicht wie es ich sonst machen soll. Kann mir jemand sagen wie es geht??
Da gibts verschiedene Ansätze... der trivialste wäre das Aufteilen der Zahl in Vor- und Nachkommastellen. Dazwischen schreibt man den Punkt von Hand. Bei cout muss man das über imbue lösen, indem man den Operator für die Kommastelle überschreibt. Manche Leute sind echt zu faul zu googlen - sorry aber das ist echt kein Hexenwerk.
Was habe ich denn gemacht? Hast du dir überhaupt meinen Ansatz angeguckt bevor du sagst "Manche Leute sind echt zu faul zu googlen - sorry aber das ist echt kein" Ich hab es in Vor und Nachkomma Anteil aufgeteilt, wie man an meinem COde sieht aber das scheint ja nur so lange zu gehen, bis Nullen direkt nach dem Komma folgen.... Und gegooglet habe ich genug aber "einfache" Ansätze habe ich nicht gefunden! Nur welche die ich nicht verstanden habe.
Google Ergebnis Nummer 3: http://stackoverflow.com/questions/14753505/c-c-printf-use-commas-instead-of-dots-as-decimal-separator im nächsten Schritt könntest du z.B. mal die Funktion locale genauer anschauen.
Du kannst bei printf auch führende Nullen mit ausgeben:
1 | printf("\nIn deutscher Schreibweise: %.0f,%04.0%f\n",vorkomma, nachkomma ); |
Ist ein etwas blöd, wenn man die Stellen Variabel machen will. Darum gibt es bie printf den * Modifier. da kannst du die Anzahl als Parameter übergeben.
1 | printf("\nIn deutscher Schreibweise: %.0f,%0*.0%f\n",vorkomma, 4, nachkomma ); |
Der Formatspecifier %f ist bei printf für double und float da. (nicht bei scanf) Und teste auch mal negative Werte.
Kriege es immer noch nicht richtig hin mit dem Komma. Wenn ich das so eingebe wie du geschrieben hast: printf("\nIn deutscher Schreibweise: %.0f,%0*.0%f\n",vorkomma, 4, nachkomma ); Bekomme ich folgendes: "In deutscher Schreibweise: 12,000%f"
DjangoG schrieb: > Kriege es immer noch nicht richtig hin mit dem Komma. > > Wenn ich das so eingebe wie du geschrieben hast: Ein bischen musst du selbst auch nachdenken bzw. dein Wissen einsetzen. Im Formatstring sind 3 Stück %, aber du hast keine 3 Werte, die in diese 3 % passen würden. (die 4 wird ja vom * im Formatstring konsumiert). Rechne immer damit, dass in Forenbeiträgen auch Tippfehler sein können. Je banaler ein Stück Code ist, desto eher enthält er Tippfehler, weil der Antwortende den Code vor dem Versenden nicht testet, eben weil er so banal ist. Um mitdenken und nicht einfach gedankenlos irgendwelche Dinge aus einem Forum übernehmen wirst du daher nicht herumkommen. Und das gilt nicht nur für Antworten aus einem Forum sondern für die ganze Programmiererei insgesammt. Wenn schon zu nichts anderem, dann erzieht das Programmieren zu exakter Beobachtung und dem Beachten von Kleinigkeiten. Denn Computer sind da gnadenlos. Was bei zwischenmenschlicher Kommunikation problemlos durchgeht (weil das Gehirn des Gegenübers das alles ausgleicht), führt in der Programmierung zu nicht funktionierenden Programmen. Wenn du in deiner Ausgabe das hier siehst
1 | 12,000%f |
also ein % Zeichen, das da nicht sein sollte, dann kannst du 100 zu 1 darauf wetten, das im Formatstring irgendwas durcheinandergekommen ist, und die Anzahl der %xxxxx Angaben nicht mit der Anzahl der an printf übergebenen Werte nach dem Formatstring übereinstimmt. Das fällt genau in die Kategorie, die ich mit 'exaktem Beobachten' meine. Kleinigkeiten, die einem Hinweise geben. Das können Kleinigkeiten in den Programmausgaben sein, das können aber auch Kleinigkeiten in der realen Welt sein, die man im Programm modellieren soll. Das können aber auch Kleinigkeiten in dem zu lernden Stoff sein, indem man zb bemerkt, dass im Formatstring die Platzhalter immer mit einem % beginnen und mit einem oder mehreren Buchstaben enden. Der Buchstabe bezieht sich auf den Datentyp des weiter hinten im Funktionsaufruf stehenden Argumentes an printf. Zwischen % und Buchstabe stehen Angaben, die die Art und Weise der Ausgabe modifizieren. Aber das Prinzip %xxx_Buchstabe bleibt in allen Fällen immer erhalten. Eine Angabe von "%0*.0%f" kann daher, rein schon aus dieser Betrachtung heraus, nicht korrekt sein. Denn zwischen % und Buchstabe kann es keinen weiteren % geben.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.