mikrocontroller.net

Forum: PC-Programmierung Datenformat interpretieren


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Zorro (Gast)
Datum:

Bewertung
-1 lesenswert
nicht 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?

Autor: Zorro (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Zorro schrieb:
> das ergibt mein Datum

meine natürlich dass es meinen Tag vom Datum ergeben würde.

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In welcher Programmiersprache willst du das denn erledigen?

In C könnte man das (allerdings nicht portabel) tatsächlich mit einem 
Bitfeld erledigen:
const char *bitfield2date(uint16_t b)
{
   const unsigned year_offset = 1900; // ?
   union
   {
      uint16_t b;
      struct
      {
         uint16_t day: 5;
         uint16_t month: 4;
         uint16_t year: 7;
      }
      s;
   }
   u;

   u.b = b;
   char result[20];
   snprintf(result, sizeof(result), "%04d-%02d-%02d",
            u.s.year + year_offset, u.s.month, u.s.day);
   return result;
}

: Bearbeitet durch Moderator
Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> In welcher Programmiersprache willst du das denn erledigen?

In Matlab.

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
const char *bitfield2date(uint16_t b)
{
   const unsigned year_offset = 1900; // ?
   unsigned int year, month, day;

   year = (b & 0xfe00) >> 9;
   month = (b & 0x01e0) >> 5;
   day = b & 0x001f;
   char result[20];
   snprintf(result, sizeof(result), "%04d-%02d-%02d",
            year + year_offset, month, day);
   return result;
}

: Bearbeitet durch Moderator
Autor: Mani (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
function [y,m,d] = getTime (x)
  a = uint16(x);
  y = (bitand(a,0xFE00)/2^9)+2000;
  m = (bitand(a,0x01E0)/2^5);
  d = bitand(a,0x001F);
end

Der Aufruf wäre dann z.B:
[y,m,d] = getTime(10036);
printf("%04d-%02d-%02d\n",y,m,d);

Autor: Mani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sollte natürlich besser getDate heißen ;-P

Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Eric B. (beric)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zorro schrieb:
> offset / byte: miliseconds
> offset / byte: seconds
> offset / byte: minute
> offset / byte: houer
function [h,m,s,u] = getTime (x)
  a = uint32(x);
  h = (bitand(a,0xFF000000)/2^24);
  m = (bitand(a,0x00FF0000)/2^16);
  s = (bitand(a,0x0000FF00)/2^8);
  u = (bitand(a,0x000000FF)/2^0);
end

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Eric B. (beric)
Datum:

Bewertung
0 lesenswert
nicht 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.

: Bearbeitet durch User
Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Arno (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Udo S. (urschmitt)
Datum:

Bewertung
0 lesenswert
nicht 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.

: Bearbeitet durch User
Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also sonst steht da nichts in der Beschreibung was zum Beispiel im Byte 
1  steht..

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zorro schrieb:
> Oder was genau wolltest du wissen?

Mach dich mal über Endianess schlau.

: Bearbeitet durch User
Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und du kannst mit dem IEEE-754 Fließkommaformat rumspielen: 
https://www.h-schmidt.net/FloatConverter/IEEE754de.html

Autor: leo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zorro schrieb:
> header =
> fread(fileID,256,'uint32').

Warum liest du 256*4 Bytes als int, wenn ab Offset 84 ein 'single' 
kommt?

leo

Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zorro schrieb:
> Kennt ihr eine
> Möglichkeit?

fseek

Georg

Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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')

Autor: Mathias A. (mrdelphi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass das fseek mal weg...

...und, klappt's dann?

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Zorro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein typecast(uint32(x),'single') schafft Abhilfe!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.