Ich habe ein Datenformat in der Form yyyy yyym mmmd dddd als 16 bit. Diese Zahl kriege ich als dezimal zahl. Wie kann ich es am sinvollsten so programmieren dass ich das Datum bekomme. Mein vorschlag ich konvertiere in binär, und addiere z.B. die ersten 5 Bitfelder das ergibt mein Datum. Ich müsste ja reisen Verschachtelungen machen mit case 1 an der Stelle 3 bedeutet Tag+=4 usw.. Aber ich glaube das geht schneller irgendwie oder?
In welcher Programmiersprache willst du das denn erledigen? In C könnte man das (allerdings nicht portabel) tatsächlich mit einem Bitfeld erledigen:
1 | const char *bitfield2date(uint16_t b) |
2 | {
|
3 | const unsigned year_offset = 1900; // ? |
4 | union
|
5 | {
|
6 | uint16_t b; |
7 | struct
|
8 | {
|
9 | uint16_t day: 5; |
10 | uint16_t month: 4; |
11 | uint16_t year: 7; |
12 | }
|
13 | s; |
14 | }
|
15 | u; |
16 | |
17 | u.b = b; |
18 | char result[20]; |
19 | snprintf(result, sizeof(result), "%04d-%02d-%02d", |
20 | u.s.year + year_offset, u.s.month, u.s.day); |
21 | return result; |
22 | }
|
:
Bearbeitet durch Moderator
Zorro schrieb: > Jörg W. schrieb: >> In welcher Programmiersprache willst du das denn erledigen? > > In Matlab. Davon habe ich leider keine Ahnung, sorry. Wird auf Bitmaskierung und -schieberei hinauslaufen. C-Äquivalent:
1 | const char *bitfield2date(uint16_t b) |
2 | {
|
3 | const unsigned year_offset = 1900; // ? |
4 | unsigned int year, month, day; |
5 | |
6 | year = (b & 0xfe00) >> 9; |
7 | month = (b & 0x01e0) >> 5; |
8 | day = b & 0x001f; |
9 | char result[20]; |
10 | snprintf(result, sizeof(result), "%04d-%02d-%02d", |
11 | year + year_offset, month, day); |
12 | return result; |
13 | }
|
:
Bearbeitet durch Moderator
Jörg W. schrieb: > Wird auf Bitmaskierung und -schieberei hinauslaufen. Ist ja in C auch so. Nur dass das der Compiler übernimmt. Zorro schrieb: > Diese Zahl kriege ich als dezimal zahl. Wie kann ich es am sinvollsten > so programmieren dass ich das Datum bekomme. Ich hätte es durch maskieren und Division/schieben gemacht:
1 | function [y,m,d] = getTime (x) |
2 | a = uint16(x); |
3 | y = (bitand(a,0xFE00)/2^9)+2000; |
4 | m = (bitand(a,0x01E0)/2^5); |
5 | d = bitand(a,0x001F); |
6 | end
|
Der Aufruf wäre dann z.B:
1 | [y,m,d] = getTime(10036); |
2 | printf("%04d-%02d-%02d\n",y,m,d); |
Vielen Danke euch! Habe allerdings eine zweite Kuriosität. In der Beschreibung steht der offset und dann was es sein sollte. offset / byte: miliseconds offset / byte: seconds offset / byte: minute offset / byte: houer 235475747 (somit sollten das die milisekunden sein an dem Die "Aufnahme" begann) 132319252 (sekunden) 4.2950e+09 (minuten) 3676 (und das die Stunden) Allerdings komme ich hier auf keine vernünftigen Werte aus diesen Zahlen.
Zorro schrieb: > offset / byte: miliseconds > offset / byte: seconds > offset / byte: minute > offset / byte: houer
1 | function [h,m,s,u] = getTime (x) |
2 | a = uint32(x); |
3 | h = (bitand(a,0xFF000000)/2^24); |
4 | m = (bitand(a,0x00FF0000)/2^16); |
5 | s = (bitand(a,0x0000FF00)/2^8); |
6 | u = (bitand(a,0x000000FF)/2^0); |
7 | end
|
Zorro schrieb: > Ich habe ein Datenformat in der Form yyyy yyym mmmd dddd als 16 bit. Mit Division / und Modulo % d = ymd % 32 m = (ymd / 32) % 16 y = ymd / 512
:
Bearbeitet durch User
Ich hatte es zwischenzeitlich schon gelöst, danke trotzdem an die letzten Posts. Habe nun ein 4 Bytes langes Single als 32-bit Floating-Point. Kann ich das genauso behandeln da es ja auch gneauso lang (4Bytes) ist? Also an dieser Adresse habe ich diesen Wert: 1.125209749000000e+09 Das soll die Framarate sein, die aber eigentlich 145Hz eingestellt war.
Zorro schrieb: > Habe nun ein 4 Bytes langes Single als 32-bit Floating-Point. Kann ich > das genauso behandeln da es ja auch gneauso lang (4Bytes) ist? Nein, weil das bestimmt kein Datum oder Uhrzeitangabe ist. Zorro schrieb: > Also an dieser Adresse habe ich diesen Wert: 1.125209749000000e+09 > Das soll die Framarate sein, die aber eigentlich 145Hz eingestellt war. Dann hast du da ein Fehler.
:
Bearbeitet durch User
Eric B. schrieb: > Dann hast du da ein Fehler. In der Formatbeschreibung steht: Typ name: Single, Lenght(Byte):4Bytes, Data Type: 32 bit Floating-Point. Wenn ich das nun so importiere: Iheader = fread(fileID,256,'uint32') habe ich da den Wert: 1.125209749000000e+09. Habe ich einen Denkfehler? Die anderen Werte wie das datum davor haben als data typ:32 bit unsigned Integer und Typ name: Dword und sind auch 4 Bytes lang.
Zorro schrieb: > Eric B. schrieb: >> Dann hast du da ein Fehler. > > In der Formatbeschreibung steht: Typ name: Single, Lenght(Byte):4Bytes, > Data Type: 32 bit Floating-Point. 32 bit Floating-Point... > Wenn ich das nun so importiere: Iheader = fread(fileID,256,'uint32') ...und uint32... > Habe ich einen Denkfehler? ...klingt zumindest, als passe es nicht zusammen ;) MfG, Arno
Zorro schrieb: > Ich habe ein Datenformat in der Form yyyy yyym mmmd dddd als 16 bit. > Diese Zahl kriege ich als dezimal zahl. Zorro schrieb: > Habe nun ein 4 Bytes langes Single als 32-bit Floating-Point. Kann ich > das genauso behandeln da es ja auch gneauso lang (4Bytes) ist? Irgendwie schmeisst du hier allerlei Zahlenformate wild durcheinander. Wie wäre es wenn du mal eine Beschreibung oder zumindest Beispiele (Binär bzw. Hex) lieferst, dann kann man dir vieleicht besser helfen.
:
Bearbeitet durch User
Also ich habe eine Beschreibung wie ein Header von dem Datenformat aufgebaut ist. darin habe ich ienmal eine Spalte mit dem Offset beginnend mit 0000 der Länge: das meiste ist DWORD lang. Dann habe ich eine Tabelle die follgendes beinhaltet: Typ name: ____ _ Length(Byte): __ Data Type: byte _________ 1Byte _______________8 bit unsigned integer word _________ 2 Bytes _____________uint16 dword____________4 Bytes_____________ uint32 Integer__________ 4 Bytes __________ uint32 Single __________ 4 Bytes __________ 32 bit Floating-Point Nun ab ofssett 0000 bis offset:0084 ist alles Length: Dword. Also importiere ich alles in Matlab mit dem Befehl: header = fread(fileID,256,'uint32'). Und habe in jeder Zeile dann eine DWORD-Lange Zahl also wie das datum wie ich es am Anfang im ersten Post beschrieben habe. Jetzt kommt aber 4 Bytes weiter also im Offset:0088 Length SINGLE.. Aus der Tabelle geht ja hervor das der Typ Single ein 32 bit Floating-Point ist. Ich es aber alles ales uint32 importiere. Also was mache ich nun um diesesn werte vom typ Single(32 bit Floating-Point richtig zu importieren/interpretieren)
Zorro schrieb: > Aus der Tabelle geht ja hervor das der Typ Single ein 32 bit > Floating-Point ist. Ich es aber alles ales uint32 importiere. Also was > mache ich nun um diesesn werte vom typ Single(32 bit Floating-Point > richtig zu importieren/interpretieren) Ist überhaupt die Bytefolge dazu klar?
Wolfgang schrieb: > Ist überhaupt die Bytefolge dazu klar? Also ab offset 0088 steht bei length:Single Description: FPS Mehr ist nicht bekannt. Also ich weiss was zum Beispiel 4 bytes darunter steht bei offsett 0084 oder auch was dannach kommt bei offset 008c, was wiederum DWord-Lang ist. Oder was genau wolltest du wissen?
Also sonst steht da nichts in der Beschreibung was zum Beispiel im Byte 1 steht..
Zorro schrieb: > Oder was genau wolltest du wissen? Mach dich mal über Endianess schlau.
:
Bearbeitet durch User
Und du kannst mit dem IEEE-754 Fließkommaformat rumspielen: https://www.h-schmidt.net/FloatConverter/IEEE754de.html
Zorro schrieb: > header = > fread(fileID,256,'uint32'). Warum liest du 256*4 Bytes als int, wenn ab Offset 84 ein 'single' kommt? leo
Also lese ich einfach bis einschließlich 84 uint32 und 088 lese ich als single ein? Und danach wieder als uint32. Ist das die Vorgehensweise?
Allerdings weiss ich nicht wie ich fread sage dass er ab einer bestimmten Stelle der Datei lesen soll, also ab 88. Kennt ihr eine Möglichkeit? Ginge es nicht einfach alles als uint32 einzulesen und den wert der Stelle 88 der eigentlich als single eingelesen werden muss zu konvertieren?
Danke! Also wenn ich einfach direkt von anfang an mit single einlsen habe ich an der stelle 88 den richtigen wert von 145 Dezimal. Lese ich aber zuerst die 34 werte mit uint32 und bewege den pointer auf den wert 35 und lese dann als single ein wert ein kommt da 0 raus. So: A = fread(fileID,34,'uint32'); fseek(fileID,35,'bof') fread(fileID,1,'single')
Zorro schrieb: > Lese ich > aber zuerst die 34 werte mit uint32 und bewege den pointer auf den wert > 35 und lese dann als single ein wert ein kommt da 0 raus. > > So: > A = fread(fileID,34,'uint32'); > fseek(fileID,35,'bof') > fread(fileID,1,'single') Ein uint32 sind 4 Byte. Du musst also auf 35*4 positionieren. Da du aber aus einem Eingabestrom liest, musst du nicht positionieren. Der Lesezeiger wird automatisch weiter gestellt.
Mathias A. schrieb: > Lass das fseek mal weg... > > ...und, klappt's dann? Dirk B. schrieb: > Ein uint32 sind 4 Byte. Du musst also auf 35*4 positionieren. Danke euch! klappt wunderbar. Und meine Idee alles als uint32 einzulesen, und dann "umzuwandeln" ist überhaupt nicht möglich oder?
Zorro schrieb: > Danke euch! klappt wunderbar. Und meine Idee alles als uint32 > einzulesen, und dann "umzuwandeln" ist überhaupt nicht möglich oder? Das ist ein Matlab Problem. Edit: Das geht mit typecast https://www.mathworks.com/help/matlab/ref/typecast.html
:
Bearbeitet durch User
Habe es probiert mit typecast(x,'single') x= 1.125209749000000e+09 kommem aber zwei werte Raus und nicht passende. Zuvor wurde x als uint32 eingelesen.
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.