IEEE754 Single Precison Zahl aus Float

Gast #1673807
Lesenswert?

Hallo liebe Gemeinde!

Ich habe ine Frage bezüglich der Umwandlung eines Floats in eine 
IEEE754-Zahl. Ich habe mir grad selber einen Algorithmus geschrieben, 
der mit die 32Bit Bitfolge aus einem loat berechnet.

Ziel ist es, diese Bitfolge später via UART zu übertragen. Ich habe auch 
schon das Forum durchsucht, jedoch passt nichts dazu auf meine Frage. Es 
geht also nicht darum, wie man diese Bitfolge errechnet, sondern ob ich 
nicht auch einfacher an die ahl rankommen kann.

Ich arbeite mit IAR Embedded Workbench und kann mir ja den Float, den 
ich eingegeben habe auch in anderen Formen darstellen lassen. Binär ist 
leider nicht dabei, aber in HEX-Darstellung kann ich mir den Float 
ebenfalls anzeigen lassen und das entspricht, wie sollte es anders sein, 
natürlich genau der Bitfolge, wie sie auch aus meinem Algorithmus 
hervorgeht.

Ist es nun möglich, ohne rechnen diesen Float als HEX-Darstellung 
einfach in seine 4 Bytes zu zerteilen und über den UART zu senden? Dann 
bräuchte man den Algorithmus ja garnicht.

Hoffe, es ist verständlich wie ich das meine.


Guß und danke!

otto
Gast #1673826
Lesenswert?

Mhh, nee, irgendwie kann die einzelnen Bytes nicht sinnvoll da raus 
holen, bzw. weiß nicht wie. Wollte das jetzt byteweise in einen char 
übertragen. Aber wegen dem Datentyp float geht das nicht so einfach.

Oder ich habe grad nen Denkfehler.
Gast #1673831
Lesenswert?

Also ich habe:

float zahl = 17769.7

uint8_t temp1 = (zahl & 0x000000FF) geht nicht, wegen ungleicher 
Datentypen

wenn ich temp1 = ((uint32_t) zahl & 0x000000FF)) dann schneidet er mir 
natürlich die Nachkommastellen ab...


Also doch den Algorithmus?
#1673846
Lesenswert?

Ich hab nicht wirklich verstanden, was du da von dir gibst.

Aber ich denke herausgelesen zu haben, dass du einen float hast und an 
die einzelnen Bytes dieses float rankommen willst.

Nichts einfacher als das.

Du nimmst die Adresse des float, castest die um auf einen uint8_t* und 
voila: schon hast du Zugriff auf die einzelnen uint8_t, also die Bytes.

Das geht mit jedem Datentyp, egal was sich dahinter versteckt. Du musst 
deinem C-Compiler nur weis machen: "Vergiss den Datentyp, der sich dort 
an dieser speziellen Adresse verbirgt. Ab jetzt tun wir so, als ob dort 
einfach nur eine Abfolge von Bytes rumlungert." Und das Werkzeug um das 
zu tun, ist ein Umcasten eines Pointers, bei dem du dem Pointer den 
speziellen Datentyp unter dem Allerwertesten wegziehst und ihm uint8_t 
unterjubelst.

1
  float a = 0.5;
2
  uint8_t* pBytes;
3

4
  pBytes = (uint8_t*)&a;
5

6
  for( i = 0; i < sizeof( float ); ++i )
7
    mach_was_mit( pBytes[i] );

Bin nicht sicher ob es das ist, was dir Kopfzerbrechen macht, aber einen 
Versuch wars, denke ich, wert.


PS: uint8_t ist der seit C99 standadisierte Datentyp für 'unsigned 
integer mit 8 Bit'. Wenn du den nicht hast: ein unsigned char tuts 
genauso.
#1673870
Lesenswert?

Und dann wird es spannend, was am anderen Ende der UART passiert.

Falls der Rechner dasselbe Datenformat hat und beide Little Endian
sind oder beide Big Endian, dann kann man sich umgekehrt wieder
die originale Float analog zusammenbauen.

Wenn nicht, dann geht es schief und führt hier zur nächsten Frage...
#1673873
Lesenswert?

Klaus Wachtler schrieb:
> Und dann wird es spannend, was am anderen Ende der UART passiert.
>
> Falls der Rechner dasselbe Datenformat hat und beide Little Endian
> sind oder beide Big Endian, dann kann man sich umgekehrt wieder
> die originale Float analog zusammenbauen.
>
> Wenn nicht, dann geht es schief und führt hier zur nächsten Frage...

:-)
Dann warten wir mal ab, was weiter passieren wird.
Gast #1673875
Lesenswert?

Ich mein, ich kann den Algorithmus ja druchlaufen lassen, aber wenn es 
schneller geht, dann wäre das natürlich auch nicht verkehrt. Bin da 
leider erst drauf gekommen, nachdem ich den Algorithmus schon fertig 
hatte.

Nochmal zur Verdeutlichung was ich meine:

Zahl:    17769.7
IEEE754: 01000110 10001010 11010011 01100110
in HEX:  46 8A D3 66

Und der Float ist halt gnauso im HEX hinterlegt, als 32Bit-Zahl lässt 
sie sich leider nicht anzeigen.

Auf jeden Fall rechnet der Computer ja genau mit diesen Gleitkommatypen.

Und da kam mir nur gerade in den Sinn, die vier HEX-Werte 46 8A D3 66 in 
einzelne chars umzupacken und mir den Algorithmus zu sparen.
#1673885
Lesenswert?

karl-otto schrieb:
> Ich mein, ich kann den Algorithmus ja druchlaufen lassen, aber wenn es
> schneller geht, dann wäre das natürlich auch nicht verkehrt. Bin da
> leider erst drauf gekommen, nachdem ich den Algorithmus schon fertig
> hatte.

Wieder mal ein Fall von:
Massenhaft Mehrarbeit, weil man sein Werkzeug (die Programmiersprache C) 
und seine Möglichkeiten nicht kennt.

Aber was red ich mir den Mund fusselig. Ist ja nicht so, dass es 
irgendwie Bücher gäbe, die einem den Umgang mit seinem Werkzeug in einer 
systematischen Art und Weise beibringen würden. Und da Programmieren ja 
auch die trivialste Tätigkeit der Welt ist, braucht man das auch nicht 
von der Pieke auf systematisch lernen. Try and Error tuts auch.
#1673889
Lesenswert?

@karl-otto:
Ja, ist schon richtig.
Du musst es nur so machen wie KHB es beschrieb.
Der kann das, weil er darin Übung hat - der letzte Thread mit
dem gleichen Thema ist noch warm.

Aber meine Warnung gilt trotzdem: Wenn die beiden beteiligten
Rechner zu nunterschiedlich sind, kann es sein, daß die
Übertragung der float 1:1 zu Unsinn führt.

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