Forum: Mikrocontroller und Digitale Elektronik float -> uint8_t: Festlegung, dass float immer 4 byte hat


von Dennis (Gast)


Lesenswert?

Morgen zusammen!

Mal ne Frage: Bei der Umwandlung von float nach uint8_t, kann man da 
irgendwie festlegen, dass der float definitiv aus 4 uint8_t besteht?

Ich frage wegen Portierung auf anderes System, wo der float evtl. nicht 
4 Byte groß ist, es programmbedingt aber unbedingt sein muss.

Gibt es da eine Möglichkeit?
1
void float_to_uint8( float data, uint8_t *buffer )
2
{
3
  uint8_t repeat;
4
  uint8_t *pointer;
5
  
6
  pointer = (uint8_t*) &data;
7
  
8
  for( repeat = 0; repeat < sizeof(float); repeat++ )
9
  {
10
    buffer[repeat] = *pointer++;
11
  }
12
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Nö, festlegen kann man das nicht.

Aber den Fehlerfall erkennen; wenn sizeof (float) was anderes als 4 
ergibt, kannst Du das irgendwo vermerken, sei es als Fehlermeldung beim 
Compilieren, sei es als Exception zur Programmlaufzeit.

von Dennis (Gast)


Lesenswert?

Mal eine Verständnisfrage noch: Geht es so auch, wie ich es jetzt 
geändert habe mit dem "data" als Zeiger. Jetzt würde ich die Adresse an 
die Funktion übergeben. Den Stern bei pointer = (uint8_t*) data; habe 
ich jetzt dann weggenommen, weil das ja dann schon die Adresse sein 
sollte.

Und wie ist es mit der letzten Zeile? Macht es einen Unterschied, ob ich

*buffer[repeat] = *pointer++;

oder

buffer[repeat] = *pointer++;

schreibe? Ein Array wird doch eh als Adresse übergeben, oder?
1
void float_to_uint8( float *data, uint8_t *buffer )
2
{
3
  uint8_t repeat;
4
  uint8_t *pointer;
5
  
6
  pointer = (uint8_t*) data;
7
  
8
  for( repeat = 0; repeat < sizeof(float); repeat++ )
9
  {
10
    *buffer[repeat] = *pointer++;
11
  }
12
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dennis schrieb:
> Und wie ist es mit der letzten Zeile? Macht es einen Unterschied, ob ich
>
> *buffer[repeat] = *pointer++;
>
> oder
>
> buffer[repeat] = *pointer++;
>
> schreibe?

Allerdings. Im ersten Fall dereferenzierst Du "buffer[repeat]", was in 
die Hose geht, weil "buffer" kein Array von Pointern ist.

Literaturhinweis:

Brian Kernighan & Dennis Ritchie, "Programmieren in C", 2. Auflage, 
Hanser-Verlag.

von Dennis (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Allerdings. Im ersten Fall dereferenzierst Du "buffer[repeat]", was in
> die Hose geht

Schon klar, aber wenn ich ein Array übrgebe, dann bekommt die Funktion 
doch die Adresse des Arrays, oder nicht? Wenn ich dann aber den Inhalt 
der Adresse beschreiben will, muss ich doch eigentlich * voranstellen. 
Was verstehe ich hier gerade falsch?

von Arc N. (arc)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Nö, festlegen kann man das nicht.

Jein, Ansi C99 sagt zumindest:
Annex F
"The C floating types match the IEC 60559 formats as follows:
— The float type matches the IEC 60559 single format.
— The double type matches the IEC 60559 double format.
— The long double type matches an IEC 60559 extended format,301) else a
non-IEC 60559 extended format, else the IEC 60559 double format."
C++0x nimmt da mal wieder einen schwachsinnigen Sonderweg und definiert 
in
3.9.1 8)
"The type double provides at least as much precision as float, ... The 
value representation of floating-point types is implementation-defined."

> Aber den Fehlerfall erkennen; wenn sizeof (float) was anderes als 4
> ergibt, kannst Du das irgendwo vermerken, sei es als Fehlermeldung beim
> Compilieren, sei es als Exception zur Programmlaufzeit.

von Kai S. (zigzeg)


Lesenswert?

Dennis schrieb:
> Rufus Τ. Firefly schrieb:
>> Allerdings. Im ersten Fall dereferenzierst Du "buffer[repeat]", was in
>> die Hose geht
>
> Schon klar, aber wenn ich ein Array übrgebe, dann bekommt die Funktion
> doch die Adresse des Arrays, oder nicht? Wenn ich dann aber den Inhalt
> der Adresse beschreiben will, muss ich doch eigentlich * voranstellen.
> Was verstehe ich hier gerade falsch?

"buffer[repeat]" ist aequivalent zu "*(buffer + repeat)". Wenn Du jetzt 
noch ein "*" voranstellst bekommst Du "**(buffer + repeat)". Das geht 
aber hoechstens wenn buffer ein Array von Pointern ist. Ist es aber hier 
nicht.

von DirkB (Gast)


Lesenswert?

Da geht auch
1
for( repeat = 0; repeat < sizeof(float); repeat++ )
2
{
3
   *buffer++ = *pointer++; // *buffer[repeat] = *pointer++;
4
}
Du kannst das ganze auch mit memcpy() erledigen oder gleich deinen &data 
an die Ausgabefunktion übergeben.

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
Noch kein Account? Hier anmelden.