Forum: Compiler & IDEs Float nach UINT32


von Norbert (Gast)


Lesenswert?

Hi,

habe grade ein kleines Variablenübergabeproblem: Und zwar habe ich eine 
float Variable und möchte diese an ein UINT32 Variable übergeben. Dabei 
möchte ich aber keine Konvertierung vornehmen, sondern wirklich den 
Speicherinhalt so eins zu eins übernehmen.

z.b: float a = 0x41A08000 (=> 20,0625)
     UINT32 b = a = 0x41A08000

Wie kann ich das am einfachsten machen. Bei mir wird die Zahl leider 
immer auf das neue Format konvertiert.

Gruß
Norbert

von Karl H. (kbuchegg)


Lesenswert?

Du kannst zb. den Umweg über einen Pointer nehmen.
Den Pointer castest du um und dereferenzierst
ihn:
    *((UINT32*)&a)

von Jörg F. (jopelabln)


Lesenswert?

ist das nicht ein typischer Fall für ein(e) 'union':

Beispiel(PseudoCode)
union{ float ufl; UINT32 ui32; UC8[4]; }tmp;
float a=20.0625;
UINT32 b;
int i;

tmp.ufl=a;
b=tmp.ui32;

for(i=0; i<4;i++)
    printf("%02x",tmp.uc[i]);   /* hier sollten die einzelnen Bytes 
ausgegeben werden - evtl. reihenfolge vertauschen */


von Thomas B. (yahp) Benutzerseite


Lesenswert?

Das hätte ich vor kurzem auch gesagt, allerdings ist das für C99 nicht 
(mehr) korrekt. Dort darf man bei Unions nur den Typ lesen, den man auch 
geschrieben hat. Es ist nicht garantiert, dass die unterschiedlichen 
Typen "übereinander" liegen, mithin muss so ein Konverter nicht 
funktionieren.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das war auch in C89 nicht garantiert.

Funktioniert normalerweise aber trotzdem, und dort, wo's nicht
funktioniert, wird der poiner cast hack ebenfalls nicht funktionieren
(der ist nämlich genaus wenig garantiert).

von Norbert (Gast)


Lesenswert?

Danke schonmal für eure Antowrten.

Gibt es denn auch eine Lösung, die kein "Hack" ist?
Letztendlich bekomme ich von einem Sensor ein FixedPoint Format 
geliefert, ausgegeben werden muss die Zahl aber im Floating Point Format 
(IEEE754). Damit ich sie aber verchicken kann, muss die Float Zahl 
wieder in vier einzelne Bytes zerlegt werden.

Oder gibt es eine Funktion, der ich eine UINT32 Zahl übergebe, und die 
mir auch wieder eine UINT32 Zahl zurückliefert, nur im Floating Point 
Format "sortiert"?


Gruß
Norbert

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Gibt es denn auch eine Lösung, die kein "Hack" ist?

Das einzig portable ist die Ausgabe als Dezimalzahl.

Wenn man diese wieder einliest, verliert man u. U. an Genauigkeit,
daher hat C99 noch zusätzliche printf- und scanf-Formate für eine
hexadezimale Aus-/Eingabe standardisiert.  Auf meinem PC sieht das
z. B. so aus:
1
$ cat > bar.c
2
#include <stdio.h>
3
4
int
5
main(void)
6
{
7
        printf("%a\n", 3.1415926);
8
        return 0;
9
}
10
^D
11
$ cc -O bar.c
12
$ ./a.out
13
0x1.921fb4d12d84ap+1
Diese geben die interne Zahlendarstellung aus, sind damit ohne
Verlust an Genauigkeit wieder einlesbar, aber nicht portabel auf
Systeme mit anderer Zahlendarstellung.

Allerdings habe ich %a nicht in printf und scanf bei avr-libc
implementiert, weil ich dafür bislang keine Anforderung hatte (und
jedes nicht benutzte Format nur Code frisst).

von Karl heinz B. (kbucheg)


Lesenswert?

> Allerdings habe ich %a nicht in printf und scanf bei avr-libc
> implementiert, weil ich dafür bislang keine Anforderung hatte

Tu's nicht.
Wenn man Float Zahl Byte-mässig verschickt, hat man bei
unterschiedlichen Systemen meist sowieso Probleme.
Werkelt auf der empfangenen Seite derselbe Compiler,
dann ist der Cast-Hack gut genug. Auch wenn der nicht
portabel oder garantiert ist, so funktioniert er gut
genug um damit leben zu können. Wer auf Byte Ebene
Übertragungen macht, ist sowieso Kummer gewohnt :-)

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.