Hallo zusammen, ich möchte den Tag eines betimmten Datums berechnen. Das Bezusgsdatum ist der 1.1.1970. Siehe Funktion ermittle_tage(). Ich teile die Anzahl der Tage zwischen den Daten durch die Anzahl der Wochentage und ermittele den Rest dieses Quotienten in Tagen. Durch eine einfache if-Abfrage möchte ich so den Tag des neues Datums berechnen. Das funktioniert nicht bei Tagen die größer als die Anzahl der Wochentage sind. Ich vermute, das ich etwas bei der Typumwandlung falsch gemacht. Danke für die Hilfe im Voraus.
> teile die Anzahl der Tage zwischen den Daten durch die Anzahl > der Wochentage und ermittele den Rest dieses Quotienten in Tagen. Den Rest bei einer int Division kriegt man mit % int i = 31; int j = 7; i / j -> 4 i % j -> 3 weil: 4 * 7 + 3 == 31 Der Rest schaut sehr kompliziert aus. Such mal im Netz nach 'Julianisches Datum'. Da gibt es eine Formel mit der du unser heutiges Datum in eine fortlaufende Tageszahl umrechnest. Zuvor schau dir aber in einem C-Lehrbuch den Abschnitt über Arrays an. Danach überlegst du dir, wie du die Anzahl der Tage aus der Monatsnummer kriegst, wenn du ein Array einsetzt. Damit fällt dann schon mal fast 70% deines Codes weg.
Natürlich bin ich die Restberechung viel zu kompliziert angegangen. Werde ich ändern. Meine Vorgehensweise war so. i/j=n 31/7 = 4,42857... n-4 = 0,428557... 0,428557... * j = 3 So in der Art müsste auch der %-operator funktionieren. Aus dem gannzahligen Rest (hier 3) möchte ich auf den Tag zurückrechnen. Ich weiß, das der 1.1.1970 ein Donnerstag ist. eine Woche später ist wieder ein Donnerstag und eine Woche und ein Tag später ist Freitag. Das funktioniert nur, solange der gannzahlige Rest kleiner gleich 3 ist. Ich muss mir das nochmal in Ruhe anschauen und das ganze auch mit einem Array machen
> So in der Art müsste auch der %-operator funktionieren.
Viel simpler.
Der Rest ist entweder ein Nebenprodukt bei der eigentlichen
Division, oder er wird so berechnet:
int i, j, Erg, Rest;
Erg = i / j;
Rest = i - Erg * j;
Über double rechnet man nur in Notfällen, weil dich die
Rundungsgenauigkeit umbringt. Du gehst mit deinem
mathematischen Wissen an die Dinge ran und für dich ist
es ganz natürlich, dass 3 * (1/3) wieder 1 ergibt
(oder auch, dass 10 * (1/10) wieder 1 ergibt).
Auf einem Computer ist das aber nicht so. Die haben nur
eine begrenzte Stellenanzahl. Selbst wenn du 1./3. als
double rechnest, kommt bei der Multiplikation mit 3.
da nicht mehr 1 heraus, sondern 0.999999999999was_weis_ich
Und das ist nun mal nicht 1. Wenn du diese Zahl auf
einen int zuweist, werden die Nachkommastellen abgeschnitten
und das Ergebnis ist 0 und nicht 1.
Auf einem Computer ist die Situation sogar noch schlimmer
als du es gewohnt bist. Durch das Binärsystem gibt es
wesentlich mehr Zahlen, die selbst bei noch so grosser
Bitzahl nicht exakt dargestellt werden können. 0.1 ist
zb. so ein Kandidat. 0.1 ist mit dem üblichen IEEE double
Schema nicht exakt darstellbar.
Das Problem liegt vermutlich in der Typumwandlung. double_quotient = (double) summe_tage / wochentage; //Typumwandlung in double Bei goßen Zahlen fällt der Rundungsfehler erst ins Gewicht. Lässt sich der Restwert von i % j dann in einer Variablen speichern? So in dieser Art: diff = (i % j) //diff = 3 Hört sich fast so an, als wenn du den %-operator selbst entwickelt hast.
Bernd wrote: > Das Problem liegt vermutlich in der Typumwandlung. > > double_quotient = (double) summe_tage / wochentage; //Typumwandlung in > double Da eher weniger. Aber du machst ja auch noch was mit dem double_quotient. > > Bei goßen Zahlen fällt der Rundungsfehler erst ins Gewicht. Nicht erst bei grossen Zahlen. Er fällt immer ins Gewicht. Und je mehr du mit double rechnetst umso schlimmer wirds. <Zitat> Rechnen mit Flieskommarithmetik ist wie das umschaufeln eines Sandhaufens. Je öfter man es macht, desto weniger Sand und desto mehr Schmutz hat man. <Zitat> > > Lässt sich der Restwert von i % j dann in einer Variablen speichern? So > in dieser Art: Sicher. Das ist ein arithmetischer Ausdruck wie jeder andere auch. > Hört sich fast so an, als wenn du den %-operator selbst > entwickelt hast. Lieb von dir. Stimmt aber nicht. Den kennst du auch. Du kennst ihn sogar schon lange! Du hast nur nicht gewusst, dass er in C mit einem % dargestellt wird. Erinnerst du dich noch? "Eine Mutter hat 17 Äpfel und 3 Kinder. Wenn alle Kinder gleich viele Äpfel bekommen, wieviele Äpfel bleiben der Mutter übrig?" Grundschule: 3te oder 4te Klasse
Das ist bei Programmiersprachen immer das Problem: eigentlich simple Sachen (wie das Äpfelproblem) in der jeweiligen Hochsprache zu implementieren. Prinzipiell ist es immer problematisch einen Computer mit der Berechnung von Fließkommazahlen zu beauftragen, weil diese Zahlen ja auch nur in einem endlichen Speicherbereich abgelegt werden können. Das habe ich schon gelernt. Nur manchmal geht es halt nicht anders. Ein weiteres Problem ist, das man sich bei Hochsprachen schlecht vorstellen kann, was da im Prozessor abläuft. Oder anders ausgedückt: wie übersetzt der Compiler die Token in 01-Arithmetik. Über das Zitat muss ich noch nachdenken. Von wem ist den das?
>Das ist bei Programmiersprachen immer das Problem: eigentlich simple >Sachen (wie das Äpfelproblem) in der jeweiligen Hochsprache zu >implementieren. Nee, ist es nicht. Man muß nur den Algorithmus wissen/herausfinden. Dann kann man das sogar in Assembler. >Ein weiteres Problem ist, das man sich bei Hochsprachen schlecht >vorstellen kann, was da im Prozessor abläuft. Oder anders ausgedückt: >wie übersetzt der Compiler die Token in 01-Arithmetik. Ist doch eigentlich ziemlich irrelevant, oder? Wenn du zu einem Ergebnis kommst, von dem weisst oder zumindest der Meinung bist, dass es richtig ist, kann es dir doch egal sein, wie der Compiler das übersetzt. Es gibt ein paar Regeln, die man beachten muß, und fertig. Ob man das jetzt in C, Basic, Pascal oder Java programmiert, sollte relativ egal sein. (Ob dieser Beitrag jetzt nötig war, sei dahin gestellt...)
"Ist doch eigentlich ziemlich irrelevant, oder? Wenn du zu einem Ergebnis kommst, von dem weisst oder zumindest der Meinung bist, dass es richtig ist, kann es dir doch egal sein, wie der Compiler das übersetzt." Du hast mich Missverstanden: Ich meinte das Problem ist zu wissen, wie der Compiler das Problem übersetzt und das Problem schließlich im Prozessor landet. Außerdem gibt es Compiler, die Probleme unterschiedlich übersetzen - der von Borland z.B. setzt eine strengere Ausformulierung des Problems voraus als der GNU.
Bernd wrote: > "Ist doch eigentlich ziemlich irrelevant, oder? > Wenn du zu einem Ergebnis kommst, von dem weisst oder zumindest der > Meinung bist, dass es richtig ist, kann es dir doch egal sein, wie der > Compiler das übersetzt." > > Du hast mich Missverstanden: Ich meinte das Problem ist zu wissen, wie > der Compiler das Problem übersetzt und das Problem schließlich im > Prozessor landet. Außerdem gibt es Compiler, die Probleme > unterschiedlich übersetzen - der von Borland z.B. setzt eine strengere > Ausformulierung des Problems voraus als der GNU. Äh. Nein Programmiersprachen, zumindest die Ernstzunehmenden, sind genormt. Es gibt also ein Dokument, welches genau beschreibt was C ist und was nicht C ist. In dem Dokument ist auch beschrieben, welche Wirkung eine Anweisung haben muss, sodass jeder Compilerhersteller seinen Compiler dahingehend prüfen kann. Damit muss ich aber nicht wissen, wie ein Compiler eine bestimmte Passage übersetzt. Es reicht völlig aus zu wissen, was auf logischer Ebene passieren muss. Wie dieses Ziel auf Maschinenspracheebene realisiert wird, ist nicht mein Bier. > Über das Zitat muss ich noch nachdenken. Von wem ist den das? Das Zitat stammt aus dem Buch: Jim Blinn, Blinns Corner - A trip down the graphics pipeline. Im Original geht es so Working with floating point is like moving piles of sand. Each time you do it, you loose a little sand and pick up a little dirt. Es stammt nicht von Blinn. Er hat es in irgendeinem Lab bei einer Firma als Wandschmuck aufgeschnappt. >> Das ist bei Programmiersprachen immer das Problem: eigentlich >> simple Sachen (wie das Äpfelproblem) in der jeweiligen >> Hochsprache zu implementieren. > > Nee, ist es nicht. Man muß nur den Algorithmus wissen/herausfinden. > Dann kann man das sogar in Assembler. Algotihmen sind ein Thema. Ein anderes Thema ist es, seine Werkzeuge zu kennen. Dein Werkzeug ist die Programmiersprache C. Du solltest dir die Zeit nehmen und dir mal ein Buch darüber zulegen. Irgendwo in den ersten 40 Seiten (von 160) wird auch auf den % Operator eingegangen. Ich finde es immer wieder erschreckend, wieviele Leute gerade in diesem Forum nach den einfachsten C-Dingen fragen, die allesamt mit einer 2-Wochen-abends-im-Bett-Lektüre vom K&R (*) zu erschlagen sind. Und dann kommt natürlich noch dazu, dass man als Programmierer ein guter Beobachter sein sollte. Wir Menschen können viele Dinge und wir machen sie unterbewusst ohne gross darüber nach- zudenken. Ein Programmierer hat gelernt zu beobachten und aus dem Beobachteten allgemeine Regeln oder Verfahren abzuleiten. Man sollte es nicht glauben, wieviele Algorithmen einfach nur Beschreibungen von Handlungsweisen sind, die jeder von uns täglich ohne Probleme macht. Nur wenn er beschreiben soll, was er denn gerade im Detail gemacht hat, dann können das die Wenigsten. (*) K&R Die übliche Kurz-Bezeichnung für "Kernighan & Ritchie, Programmieren in C"
Ok danke für die Tips, habe das Problem jetzt behoben und das Programm mit meinem Geburtsdatum (einem Donnerstag) getestet. Natürlich reicht dieser Test bei weitem nicht aus. Kommerzielle Entwickler machen das mit Grenzwertanalysen und vorheriger Festlegung der Äquivalenzklassen. Das Buch vom Balzert (Lehrbuch der SW-Technik) bechreibt einiges zu diesem Thema. Über C habe ich folgende Bücher: H. Erlenkötter und die RRZN-Schriften der Uni Hannover. Die K&R-Bibel scheint abgespaced zu sein. Lohnt es sich diese zu kaufen? Du meinst mit Normung der Compiler sicher den ANSI-Standard?
>Die K&R-Bibel scheint abgespaced zu sein. Finde ich nicht. Nur die erste deutsche Ausgabe ist "abgespaced", da sie scheinbar von einem Computer übersetzt wurde. >Du meinst mit Normung der Compiler sicher den ANSI-Standard? Jepp. > Du hast mich Missverstanden: Ich meinte das Problem ist zu wissen, wie > der Compiler das Problem übersetzt und das Problem schließlich im > Prozessor landet. Das kann dir doch eigentlich egal sein, solange die Logik in deinem Programm stimmt. >Außerdem gibt es Compiler, die Probleme unterschiedlich übersetzen - der von >Borland z.B. setzt eine strengere Ausformulierung des Problems voraus als >der GNU. "Verschiedene" C-Compiler kann man man mit verschiedenen Dialekten einer natürlichen Sprache (z.B. Deutsch) vergleichen: Es gibt eine grundlegende Sprache, auf die man sich geeinigt hat. Durch regionale Unterschiede gibt es gewisse Erweiterungen. Anders ist es bei C und den verschiedenen Compilern auch. >strengere Ausformulierung des Problems Inwiefern? Compiler beschäftigen sich nicht mit Problemen, sondern mit dem Übersetzen von einer Sprache in eine andere - quasi Dolmetscher. Im Regelfall wird eine Hochsprache in Maschinencode übersetzt - irgendwo habe ich mal einen Basic-C-Compiler gesehen, der aus einem Basic-Quellcode C-Quellcode gemacht hat...
Hallo Captain Core. Ich habe es nach der Wochentagsberechnung wie das auch in Wiki beschrieben ist gemacht. In Wiki habe ich allerdings dafür nicht nachgeschaut. Das mit dem Doomsday blick ich noch nicht. Allein für die Ermittlung dieses Tages braucht man ja scho eine Monsterformel.
Hallo Bernd, Ich habe nach einem bischen Suchen im Netz auf Seite (http://lefti.amigager.de/Computer/Java/main.html) eine recht simple Methode gefunden und in einem kleinen C-Programm ein wenig ausgetestet. Ist kein Doomsday, aber es funktioniert scheinbar... Kannst ja mal probieren. Grüsse Captain ore
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.