Datenformat interpretieren

Gast #5978843
Lesenswert?

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?
Moderator Persönliche Seite #5978852
Lesenswert?

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
}
Moderator Persönliche Seite #5978882
Lesenswert?

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
}
Gast #5978916
Lesenswert?

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);
Gast #5979158
Lesenswert?

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.
Gast #5982597
Lesenswert?

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.
#5982646
Lesenswert?

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.
Gast #5982677
Lesenswert?

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.
Gast #5982758
Lesenswert?

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
#5982773
Lesenswert?

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.
Gast #5983078
Lesenswert?

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)
Gast #5983091
Lesenswert?

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?
Gast #5983100
Lesenswert?

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?
Gast #5983315
Lesenswert?

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?
Gast #5983336
Lesenswert?

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')
#5983448
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren