mikrocontroller.net

Forum: Compiler & IDEs Float nach UINT32


Autor: Norbert (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Jörg Friedrich (jopelabln)
Datum:

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


Autor: Thomas B. (yahp) Benutzerseite
Datum:

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

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

Autor: Norbert (Gast)
Datum:

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
$ cat > bar.c
#include <stdio.h>

int
main(void)
{
        printf("%a\n", 3.1415926);
        return 0;
}
^D
$ cc -O bar.c
$ ./a.out
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).

Autor: Karl heinz Buchegger (kbucheg)
Datum:

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

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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