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
Du kannst zb. den Umweg über einen Pointer nehmen. Den Pointer castest du um und dereferenzierst ihn: *((UINT32*)&a)
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 */
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.
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).
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
> 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).
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.