C Eine Uhr im "HH:MM:SS.Z" Format ausgeben

KROKvsKROK

Ensign
Registriert
Apr. 2013
Beiträge
149
Hallo,

Ich möchte in C eine Uhr auf der Konsole im "HH:MM:SS:Z" Format ausgeben, wobei "Z" für Zehntelsekunden steht.
Die Uhr startet also mit : 00:00:00.0

Das ganze soll aber dadurch erreicht werden, indem man die hier 2-stelligen Dezimalzahlen in ihre Zehnterpotenzen zerlegen soll und dann entsprechent für die Ausgabe formatiert. Man soll also nicht einfach bei z.B. "01:05:15.6" die Nullen vor der jeweiligen Zahl vorschreiben.
Außerdem sollte das ganze auch ohne Divisionen umgesetzt werden.

Mein einziger Ansatz bisher ist, dass ich (als Beispiel jetzt für die Sekunden "SS") mir die 2 Ziffern dadurch hole, indem ich den Modulo und Divisionsoperator nutze (Algorithmus: Ziffern einer Zahl erhalten). Dabei dividiere ich allerdings (was ja unerwünscht ist aber unumgänglich, da ich ja durch 10 dividiere. Würde ich durch eine 2er-Potenz dividieren, könnte ich ja Bits verschieben) und eine wirkliche Zerlegung in Zehnerpotenzen verwende ich auch nicht.

Ich versteh also nicht ganz wie ich das ganze umsetzen soll bzeiheungsweise wie das funktionieren soll.
 
Modulo ist keine Division, auch wenn es oft vereinfacht so erklärt wird. Für Zehntelsekunden die Zeit aus einer Quelle holen, die genauer als eine Sekunde ist. Details sind plattformabhängig. Außerdem: Standardhinweis zu Hausaufgaben.
 
asdfman schrieb:
Modulo ist keine Division, auch wenn es oft vereinfacht so erklärt wird.
Man kann eine Modulo-Rechnung auch nur mit Multiplikation und Addition schreiben, aber ob diese Variante auch so dann letzendlich in C beim "%"-Operator implementiert ist?

asdfman schrieb:
Für Zehntelsekunden die Zeit aus einer Quelle holen, die genauer als eine Sekunde ist. Details sind plattformabhängig.
Die Zehntelsekunden kriegt man doch ganz einfach mit "Sleep(100);". Ob das jetzt die genauste Variante ist weiß ich nicht, aber das ist nicht der Kern der Aufgabe. Der Kern ist die Lösung mithilfe des Zerlegens der Zahlen in Zehnerpotenzen (ohne Division). Und da komme ich nicht weiter.
 
Wenn Division durch 2 nicht erlaubt ist, dann multipliziere eben mit 0,5.
 
KROKvsKROK schrieb:
Man kann eine Modulo-Rechnung auch nur mit Multiplikation und Addition schreiben, aber ob diese Variante auch so dann letzendlich in C beim "%"-Operator implementiert ist?

Du hast wohl den Sinn der Abstraktion in höheren Programmiersprachen missverstanden. Der besteht vor Allem darin, dass man die tieferliegende Implementierung ignorieren und die Sprachfeatures wie primitive verwenden kann.

Die Frage danach, wie etwas "in C implementiert ist", ist außerdem auch sinnlos. Der Standard schreibt vor, welches Verhalten ein Operator oder sonstiges Feature zu zeigen hat. Wie man zu dem geforderten Ergebnis kommt, ist jedem selbst überlassen und als Programmierer sollte man da auch keine Annahmen machen, weil sie sich jederzeit ändern können. Als Beispiel: qsort() ist oft als merge sort implementiert. Das ist aber für den Benutzer der Funktion irrelevant. Sie sortiert. Ende. Keine weiteren Annahmen über Interna.

Und zuletzt: Modulo ist keine Division. Das zählt (für mich zumindest ymmv).

Die Zehntelsekunden kriegt man doch ganz einfach mit "Sleep(100);". Ob das jetzt die genauste Variante ist weiß ich nicht, aber das ist nicht der Kern der Aufgabe. Der Kern ist die Lösung mithilfe des Zerlegens der Zahlen in Zehnerpotenzen (ohne Division). Und da komme ich nicht weiter.

Das ist eine nicht besonders empfehlenswerte Zeitquelle, aber sie ist:

- genauer als eine Sekunde
- plattformabhängig

€: Noch ein Vorschlag: mktime(). Die Funktion ist sogar standardisiert, allerdings auch nur auf die Sekunde genau, deshalb musst du für die Zehntel immer noch frickeln.
 
Zuletzt bearbeitet:
e-Laurin schrieb:
Wenn Division durch 2 nicht erlaubt ist, dann multipliziere eben mit 0,5.

Stimmt....Ich hatte zuerst zu stark auf Bit-Verschiebungen geschaut.

Damit könnte ich meinen Ansatz nun Divisionsfrei bekommen. Aber ich verwende ja trozdem noch nirgends Zehnerpotenzen. Mir ist auch der Sinn dafür nicht klar bzw. wie es damit gehen sollte.

Ich würde derzeit einfach für Stunden, Minuten, Sekunden eine Variable anlegen. Zusätzlich für jede dieser Variablen noch 2 weitere Variablen, welche die einzelnen Ziffern festhalten sollen. Wenn ich dann z.B. Minuten in die einzelnen Ziffern zerlegen will und dabei feststelle, dass Minuten<10 ist, dann wäre die linke Ziffer von Minuten eben 0.
So würde ich das zurzeit lösen. Wozu brauche ich dort Zehnerpotenzen bzw. wie sollte es damit funktionieren?
 
Arr, war mit meinem Edit zu langsam. Das Alter :(

€: Und die Funktion, die ich eigentlich meinte heißt localtime(). Mea maxima culpa.
 
Zuletzt bearbeitet:
Für die Division durch 10 gibt es mehrere Mölichkeiten:


1. Möglichkeit: "switch"
Code:
switch(z)
{
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:  q=0;
             break;
    case 10:
...
    case 19: q=1;
             break;
....



2. Möglichkeit: "Lookup-Tabelle"
siehe auch http://de.wikipedia.org/wiki/Lookup-Tabelle

Pseudo-Code:

lut = { 9, 19, 29, 39, 49, 59};
Iteriere über alle Indizes von lut
{
wenn zahl<= Eintrag in der lut dann quotient= index;
}



3. Möglichkeit: "10er Logarithmus"

Beispiel: 23

log(23)=1,362
1,362-1= 0,362
10 hoch 0,362= 2,3
Ganzzahl(2,3)= 2


4. Möglichkeit: "geschickte mathematische Operationen"

Code:
 z   a     b     c     s     q
    z>>1  z>>2  z>>3  a+b+c s>>3
--------------------------------
10    5     2     1     8    1
20   10     5     2    17    2
30   15     7     4    26    3
40   20    10     5    35    4
50   25    12     6    43    5


HTH

BigNum
 
Jetzt kommst Du der Lösung Deiner Hausaufgabe langsam näher.
Lösen musst Du die alleine, Du bekommst aber noch ein paar Denkanstöße.

KROKvsKROK schrieb:
Ich würde derzeit einfach für Stunden, Minuten, Sekunden eine Variable anlegen. Zusätzlich für jede dieser Variablen noch 2 weitere Variablen, welche die einzelnen Ziffern festhalten sollen.
Gut so.

KROKvsKROK schrieb:
Wenn ich dann z.B. Minuten in die einzelnen Ziffern zerlegen will und dabei feststelle, dass Minuten<10 ist, dann wäre die linke Ziffer von Minuten eben 0.
So würde ich das zurzeit lösen. Wozu brauche ich dort Zehnerpotenzen bzw. wie sollte es damit funktionieren?
Die "linke Ziffer" ist die Zehnerpotenz oder auch kurz "die Zehner".
Das Prüfen mit < oder > ist eine sehr gute Idee, damit findest Du schon mal raus, ob es "Zehner" gibt. Wie viele kann man zählen.

Da Du, wie viele andere auch, ein Problem hast, eine Division mit Hilfe anderen Rechenarten zu beschreiben, überlege mal, wie Kinder an das Gegenstück Multiplikation oft herangeführt werden?
Wie kommt ein Kind an die Lösung von z.B. 4 mal die 3 ohne je eine Multiplikation gemacht zu haben?
Oder wie rechnest Du im Kopf z.B. 4 x 17?
Kann die Antwort mit Hilfe einer Schleife realisiert werden?

Die Aufgabe kann vollständig mit Ganzzahlen und Grundrechenarten gelöst werden.
 
HDScratcher schrieb:
Die "linke Ziffer" ist die Zehnerpotenz oder auch kurz "die Zehner".
Das Prüfen mit < oder > ist eine sehr gute Idee, damit findest Du schon mal raus, ob es "Zehner" gibt. Wie viele kann man zählen.

Nehmen wir als Beispiel die Minutenzahl 12 (Ich beziehe mich hier im stark vereinfachten Beispiel erstmal nur rein auf die Minuten):
- Ich zerlege die Zahl 12 erstmal in ihre einzelnen Ziffern und weise diese jeweils den Ziffernvariablen für die Minuten zu.

Was haben wir also?

Code:
int minutenzahl = 12;
//Die Umwandlung in Ziffern lasse ich hier im Beispiel zur Übersicht weg
int minutenzahlZehnerstelle = 1;
int minutenzahlEinerstelle = 2;

Nun könnte man die Minuten einfach wie folgt ausgeben:

Code:
printf("%d%d", minutenzahlZehnerstelle, minutenzahlEinerstelle);

Wäre hier die Minutenzahl statt 12 nun z.B. 5, dann würde ich im Code an der Stelle, an der ich die Minutenzahl in ihre Ziffern zerlege ja mit
Code:
if(minitenzahl<10) minutenzahlZehnerstelle=0;
die Zehnerstelle direkt auf 0 setzen und hätte die 0 dann auch wie gewünscht in der Ausgabe stehen.

Die Frage ist jetzt aber ob das wirklich so gewünscht ist?
Gilt also (hier für diese Aufgabe) "Zerlegung einer Zahl in ihre Ziffern = Zerlegung einer Zahl in ihre Zehnerpotenzen" ?
(Falls ja, dann ist nun alles klar.)
 
KROKvsKROK schrieb:
"Zerlegung einer Zahl in ihre Ziffern = Zerlegung einer Zahl in ihre Zehnerpotenzen"
Ja, in unserem Zehnersystem (Stellenwertsystem zur Basis 10) entspricht jede Stelle doch eine Zehnerpotzenz und die Ziffer zeigt an, wie häufig diese Zehnerpotenz vorhanden ist.

z.B. 375
= 3 * 100 + 7 * 10 + 5 * 1
= 3 * 102 + 7 * 101 + 5 * 100



Ich sehe die Aufgabe, mit der Bedinung keine Division zu nutzen, so dass Ihr damit lernen sollt Algorithmen zu entwickeln, denn Programmieren ist nicht nur die Kenntnis über Syntax und schon vorhanden Funktionen.

KROKvsKROK schrieb:
Code:
//Die Umwandlung in Ziffern lasse ich hier im Beispiel zur Übersicht weg
Dass ist wohl das wichtigste an der Aufgabe, vielleicht noch interessant auf welchem Weg der Überlauf zu Sekunden, Minuten und Stunden realisiert wird und der Rest ist dann nur Textausgabe.
 
Zurück
Oben