___ qstnhdr ___ Was ist die kleinste Anzahl von Bytes, die einen Zeitstempel speichern können?
___ qstntxt ___
Ich möchte meine eigene Zeitstempeldatenstruktur in C erstellen.
TAG (0 - 31), STUNDE (0 - 23), MINUTE (0 - 59)
Was ist die kleinste mögliche Datenstruktur?
___ answer595932 ___
- Monat: Bereich 1 - 12 = & gt; 4 Bits
- Datum: Bereich 1 - 31 = & gt; 5 Bits
- Stunde: Bereich 0 - 24 = & gt; 5 Bits
- Minute: Bereich 0 - 60 = & gt; 6 Bits
Sie können ein Bitfeld verwenden und ein Compiler / Plattform-spezifisches Pragma verwenden, um es dicht zu halten:
%Vor%
Aber brauchst du das wirklich? Wären die Standardzeitfunktionen nicht ausreichend? Bitfields variieren je nach Architektur, Padding und so weiter ... kein tragbares Konstrukt.
___ answer595944 ___
Meinst du HOUR 0-23 und MINUTE 0-59? Ich habe von Schaltsekunden gehört, aber keine Schaltminuten oder Stunden.
%Vor%
Sie können also diese Werte 16 Bits oder 2 Bytes anpassen. Ob das eine gute Idee ist oder nicht, ist eine ganz andere Frage.
___ answer595930 ___
Nun, Sie könnten alles in einem %code% packen (das sind 2 Bytes , 5 Bits für den Tag, 5 Bits für die Stunde, 6 Bits für die Minute). .. und verwenden Sie einige Verschiebungen und Maskierung, um die Werte zu erhalten.
%Vor%
oder Verwenden von Makros
%Vor%
(Sie haben Monat / Jahr in Ihrer aktuellen Version der Frage nicht erwähnt, deshalb habe ich sie weggelassen).
[ Bearbeiten : Verwenden Sie %code% - nicht signiert %code% .]
___ answer596111 ___
Warum nicht einfach die (4-Byte?) Ausgabe der C %code% -Funktion mit %code% als Argument verwenden. Es ist nur die Unix-Epoche (d. H. Die Anzahl der Sekunden seit dem 1. Januar 1970). Wie Joes Antwort gibt es Ihnen viel mehr Platz zum Wachsen als jede Antwort, die versucht, in Monaten und Tagen und Jahren in Bits zu packen. Es ist Standard. Das Konvertieren der %code% -Variable in eine tatsächliche Zeit ist im Standard C (unter Unix, zumindest) trivial und wenn Sie eine Datenstruktur haben, die eine 3-Byte-Variable enthalten soll, kann sie meistens auf 4 Bytes aufgerundet werden trotzdem.
Ich weiß, dass Sie versuchen, stark für die Größe zu optimieren, aber 4 Bytes sind verdammt klein. Selbst wenn Sie das oberste Byte abschneiden, erhalten Sie immer noch 194 Tage davon.
Sie können noch mehr daraus machen, indem Sie die Zeit von %code% nehmen und sie vor dem Speichern durch 60 dividieren, indem Sie sie auf eine Minute kürzen und speichern. 3 Byte davon gibt Ihnen, wie oben gezeigt, 388 Monate, und für 2 Bytes können Sie 45 Tage speichern.
Ich würde mit der 4-Byte-Version gehen, einfach weil ich den Unterschied zwischen 2, 3 und 4 Bytes überhaupt nicht als wichtig oder wesentlich für ein laufendes Programm betrachte oder nicht (es sei denn, es ist ein Bootloader). Es ist einfacher zu bekommen und einfacher zu handhaben und wird Ihnen wahrscheinlich am Ende viele Kopfschmerzen ersparen.
EDIT: Der Code, den ich gepostet habe, hat nicht funktioniert. Ich hatte 3 Stunden Schlaf und ich werde herausfinden, wie man das bisschen richtig dreht. Bis dahin können Sie das selbst implementieren.
___ answer595941 ___
Für den Anwendungsfall, den Sie beschreiben (Minutenauflösung in einem Bereich von 31 Tagen), würde ich nur einen 16-Bit-Minutenzähler verwenden. Wenn Sie diese Daten serialisieren (auf Datenträger, Netzwerk), können Sie eine Integer-Codierung mit variabler Länge verwenden, um Byte für kleine Werte zu speichern.
___ answer596007 ___
nur um eine Alternative anzubieten:
- Wenn Sie nur eine Auflösung auf Minutenebene benötigen,
- und Sie überschreiten keine Datumsgrenzen (Monat / Jahr)
- und Ihre Nachrichten sind sequenziell mit garantierter Zustellung
Dann können Sie den Zeitstempel als Offset vom Zeitstempel der letzten Nachricht speichern.
In diesem Fall benötigen Sie nur genügend Bits, um die maximale Anzahl von Minuten zwischen Nachrichten zu speichern. Wenn Sie beispielsweise Nachrichten im Abstand von maximal 255 Minuten ausgeben, reicht ein Byte aus.
Beachten Sie jedoch, dass die erste Nachricht möglicherweise einen absoluten Zeitstempel in ihrer Nutzlast für die Synchronisation enthalten muss.
[Ich sage nicht, das ist eine gute Lösung - es ist ziemlich fragil und macht eine Menge Annahmen - nur eine Alternative]
___ answer595966 ___
Im Allgemeinen können Sie diese Antwort wie folgt berechnen (wobei log2 der Logarithmus der Basis 2 ist, d. h. die Anzahl der Bits):
-
Wenn Sie Shifts und Masken verwenden möchten, um die Daten ein- und auszugeben, nehmen Sie log2 () der Anzahl der möglichen Werte für jedes Feld, runden Sie auf (um Bits zu erhalten), fügen Sie die Ergebnisse hinzu (um ganze Bits zu erhalten) , dividiere durch acht (Gesamtbytes, w. Bruchbytes) und runder wieder (Gesamtbytes).
log2 (60) + log2 (60) + log2 (24) + log2 (31) + log2 (12) = 6 + 6 + 5 + 5 + 4 = 26 Bits = 4 Bytes
-
Wenn Sie die Felder durch Multiplizieren mit & amp; hinzufügen / teilen & amp; modulo, multipliziere die Anzahl der möglichen Werte für jedes Feld und nimm log2 () davon, dividiere durch acht und richte auf.
log2 (60 * 60 * 24 * 31 * 12) = 24.9379 Bits = 4 Bytes
-
Sie können einen winzigen zusätzlichen Platz sparen, indem Sie nicht-isoformale Felder kombinieren (z. B. Speichern des Jahrestages statt Monat und Tag des Monats), aber es lohnt sich selten.
log2 (60 * 60 * 24 * 366) = 24.91444 Bits = 4 Bytes
- MarkusQ "lehre einen Mann zu fischen"
___ answer595969 ___
Hinweis: Die ursprüngliche Frage wurde bearbeitet und der Monat ist nicht mehr erforderlich. Die ursprünglichen Berechnungen waren unten:
Es ist einfach eine Frage, wie viel Rechenzeit Sie machen wollen. Die beste Möglichkeit, es zu packen, ist, wenn Sie Ihren eigenen Typ erstellen und die folgende Formel verwenden können, um von und in die entsprechende Ganzzahl zu konvertieren:
Gültige Bereiche sind:
%Vor%
Sie können eine Reihenfolge auswählen, in der die Werte gespeichert werden (ich behalte sie in der obigen Reihenfolge).
%Vor%
Machen Sie ein bisschen Multiplikation / Division, um die Werte unter Verwendung der folgenden Formel als Richtlinie zu konvertieren:
%Vor%
Sie haben also den Minimalwert 0 und den Maximalwert %code% , was 535.679 ist. Sie benötigen also mindestens 20 Bit, um diesen Wert als vorzeichenlose Ganzzahl ( %code% ) zu speichern.
Wenn Sie Dinge schwierig machen, aber ein Byte speichern wollen, können Sie 3 Bytes verwenden und sie selbst manipulieren. Oder Sie können ein int (32-Bit) verwenden und normalerweise mit einfachen mathematischen Operatoren arbeiten.
Aber da ist noch ein bisschen Platz zum Spielen, also schauen wir mal, ob wir das leichter machen können:
Gültige Bereiche sind wiederum:
%Vor%
Das sind insgesamt 20 Bits und wirklich einfach zu manipulieren. Sie gewinnen also nichts, wenn Sie etwas weiter komprimieren als einfache Bit-Verschiebung, und Sie können den Wert folgendermaßen speichern:
%Vor%
Wenn Sie sich nicht um den Monat kümmern, ist das engste, was Sie bekommen können:
%Vor%
Sie haben einen Bereich von 0 bis 44.639, der genau in 16-Bit %code% passt.
Es gibt aber auch Raum, um damit zu spielen, also schauen wir mal, ob wir das leichter machen können:
Gültige Bereiche sind wiederum:
%Vor%
Das sind insgesamt 16 Bits und wieder wirklich einfach zu manipulieren. Also .... den Wert wie folgt speichern:
%Vor%
___ tag123c ___ C ist eine universelle Computerprogrammiersprache, die für Betriebssysteme, Bibliotheken, Spiele und andere Hochleistungsanwendungen verwendet wird. Dieses Tag sollte bei allgemeinen Fragen zur C-Sprache verwendet werden, wie in der Norm ISO 9899: 2011 definiert. Fügen Sie ggf. ein versionsspezifisches Tag wie c99 oder c90 für Fragen zu älteren Sprachstandards hinzu. C unterscheidet sich von C ++ und es sollte nicht mit dem C ++ - Tag kombiniert werden, wenn ein rationaler Grund fehlt.
___ answer596029 ___
60 Minuten / Stunde bedeutet, dass Sie mindestens 6 Bit benötigen, um die Minute zu speichern (seit 59. Minute == 111011b), während 24 Stunden / Tag weitere 5 Bit bedeutet (23. Stunde == 10111b). Wenn Sie eines der (möglicherweise) 366 Tage / Jahr berücksichtigen möchten, benötigen Sie 9 weitere Bits (366. Tag (365 wenn Tag 1 == 0) == 101101101b). Wenn Sie also alles in einem rein zugänglichen Format speichern möchten, benötigen Sie 20 Bits == 3 Bytes. Alternativ würde das Hinzufügen eines Monatsfelds den gesamten möglichen Days-Wert von 366 auf 31 - bis zu 5 Bits mit 4 weiteren Bits für den Monat ändern. Dies würde auch Ihnen 20 Bits oder 3 Bytes mit 4 Bits zur Verfügung stellen.
Umgekehrt, wenn Sie das Datum nur wenige Minuten nach dem Startdatum verfolgen, geben 3 Bytes Ihnen eine Auflösung von 16.777.215 Minuten, bevor Sie wieder auf 0 übergehen - das sind ungefähr 279.620 Stunden, 11.650 Tage und ungefähr 388 Monate, und das ist die Verwendung aller 24 Bits. Das ist wahrscheinlich ein besserer Weg, wenn Sie sich nicht um Sekunden kümmern, und wenn es Ihnen nichts ausmacht, ein wenig Ausführungszeit zu nehmen, um die Stunde, den Tag und den Monat zu interpretieren. Und wäre das viel einfacher zu erhöhen!
___ tag123timestamp ___ Ein Zeitstempel ist der Zeitpunkt, zu dem ein Ereignis von einem Computersystem aufgezeichnet wird. Der Zeitstempelbegriff kann sich auch auf die Unix-Zeit oder auf den Zeitstempeldatentyp beziehen.
___ answer595959 ___
5 Bits für den Tag plus
5 Bits für die Stunde plus
6 Bits für die Minute entsprechen einem unsigned short. Jede weitere Komprimierung würde den benötigten Speicherplatz nicht reduzieren und würde die Code-Komplexität und die CPU-Nutzung erhöhen.
___ answer590000 ___
Nun, abgesehen von der überflüssigen STUNDE 24 und STUNDE 60, haben wir 31 x 24 x 60 = 44.640 mögliche eindeutige Zeitwerte. 2 ^ 15 = 32.768 & lt; 44.640 & lt; 65,536 = 2 ^ 16, also benötigen wir mindestens 16 Bits (2 Bytes), um diese Werte darzustellen.
Wenn wir nicht jedes Mal Modulo-Arithmetik verwenden wollen, um auf die Werte zuzugreifen, müssen wir sicherstellen, dass jedes in seinem eigenen Bitfeld gespeichert wird. Wir benötigen 5 Bits zum Speichern des DAY, 5 Bits zum Speichern der HOUR und 6 Bits zum Speichern der MINUTE, die immer noch in 2 Bytes passt:
%Vor%
Einschließlich der MONTH würde unsere einzigartigen Zeitwerte um einen Faktor von 12 erhöhen, was 535.680 eindeutige Werte ergibt, die mindestens 20 Bits zum Speichern erfordern würden (2 ^ 19 = 524.288 & lt; 535.680 & lt; 1.048.576 = 2 ^ 20), das erfordert mindestens 3 Bytes.
Um Modulo-Arithmetik zu vermeiden, benötigen wir ein separates Bitfeld für MONTH, das nur 4 Bits benötigen sollte:
%Vor%
Beachten Sie jedoch in beiden Beispielen, dass C bevorzugt, dass seine Datenstrukturen on-cut sind - das heißt, sie sind Vielfache von 4 oder 8 Bytes (normalerweise), so dass sie Ihre Datenstrukturen über das Minimum hinaus auffüllen können notwendig.
Zum Beispiel auf meinem Rechner,
%Vor%
druckt:
%Vor%
___ answer596275 ___
Um dies ohne Verlust der Allgemeinheit zu vereinfachen,
Tag (0 - 30), Stunde (0 - 23), Minute (0 - 59)
%Vor%
Der Maximalwert der Codierung ist 44639, was etwas weniger als 16 Bit ist.
Edit: rampion sagte im Grunde das Gleiche. Und das bringt Ihnen die minimale Darstellung, die kleiner ist als die bitweise verschachtelte Darstellung.
___