2015-11-10 6 views
9

Ich verwende den XC32-Compiler von Microchip, der auf dem Standard-C-Compiler basiert.Interpretieren eines 32bit unsigned long als Single Precision IEEE-754 Float in C

Ich lese einen 32bit-Wert von einem Gerät in einem RS485-Netzwerk und speichert dies in einem unsigned long, dass ich als DWORD typedef definiert habe.

heißt

typedef DWORD unsigned long; 

Wie es aussieht, wenn ich diesen Wert auf einen Schwimmer typisieren, der Wert I erhalten, ist im Grunde die Floating-Point-Version davon ist Integer-Darstellung und nicht der richtige IEEE-754 interpretiert Schwimmer.

dh

DWORD dword_value = readValueOnRS485(); 
float temp = (float)dword_value; 

Hier dword_value würde im HEX-Format als 0x4366C0C4 kommt durch, die als eine Dezimalzahl als 1130807492 dargestellt werden würde, so dass die Schublade gesteckt dies zu einem Schwimmer einfach gibt mir 1,130807492 * 10^9 oder 1130807492,0 was ich nicht will.

Ich mag die einfache Genauigkeit IEEE-754-Darstellung, die mir einen Float-Wert von 230,75299072265625

für mich So klar typecasting zu schweben nicht geben würde funktionieren. Ich brauche eine Methode, die diese Form mir konvertieren kann. Ich habe überall in der XC32-Bibliothek nachgeschaut und kann nichts finden.

Kennt jemand eine vordefinierte Methode, die diese Interpretation richtig für mich tut? Oder gibt es vielleicht eine vorgeschlagene Methode, die ich schreiben kann? Ich versuche zu vermeiden, meinen eigenen Code für diese spezielle Aufgabe zu schreiben, da ich mir Sorgen mache, dass ich keine effiziente Lösung finde, wenn C dafür bereits eine Funktion hat.

Die interessante Sache ist, wenn ich dies zu einem char * zu tun, wird der Wert an diesem Zeichen * dargestellt korrekt als 230.75:

sprintf(random_char_pointer, "%.2f, dword_value); 

Hier Druck random_char_pointer zu Bildschirm gibt mir 230.75 so muss der sprintf sein das Dolmetschen für mich richtig handhaben. Ich gehe daher davon aus, dass es für mich schon etwas in C gibt. Kann jemand helfen?

+2

'f = * (float *) & uvalue;' (plus/minus Ausrichtung Überlegungen) – joop

+0

@joop Ist das nicht gleichbedeutend mit einem 'float'? – Downvoter

+1

Nein, ich werfe einen unsigned int * -Zeiger * auf einen float * -Zeiger * und dereferenziere ihn. – joop

Antwort

7

Der empfohlene Weg, Sachen wie dies zu tun ist, eine Gewerkschaft zu verwenden:

union { 
    DWORD w; 
    float f; 
} wordfloat; 

wordfloat.w = dword_value; 
temp = wordfloat.f; 

Dies tut, was Sie wollen nach ISO 9899: 2011 §6.5.2.3 ¶3 Fußnote 95:

Ein Postfix-Ausdruck gefolgt vom .-Operator und einem Bezeichner bezeichnet ein Mitglied einer Struktur oder eines Vereinigungsobjekts. Der Wert ist der des benannten Members 95) und ist ein Lvalue, wenn der erste Ausdruck ein Lvalue ist. Wenn der erste Ausdruck einen qualifizierten Typ hat, hat das Ergebnis die so qualifizierte Version des Typs des angegebenen Mitglieds.

95) Wenn das Element, das zum Lesen des Inhalts eines Union-Objekts verwendet wird, nicht mit dem Element übereinstimmt, das zuletzt zum Speichern eines Werts im Objekt verwendet wurde, wird der entsprechende Teil der Objektdarstellung des Werts als Objekt neu interpretiert Darstellung in dem neuen Typ wie in 6.2.6 beschrieben (ein Prozess, der manchmal "type punning" genannt wird). Dies könnte eine Trap-Repräsentation sein.

+0

Danke FUZxxl werde dies versuchen und dich wissen lassen –

+0

Ich bin gespannt, woher kommt die 'volatile' Empfehlung? Die Fähigkeit, diese Art der Dateninterpretation durchzuführen, ist einer der Hauptgründe dafür, warum (gewöhnliche, nichtflüchtige) "Vereinigungen" in C. existieren. – user4815162342

+1

Nein, der Volatile wird nicht benötigt (und grundsätzlich unsinnig, weil die beiden Mitglieder denselben Standort haben) caching ihrer Werte würde das Ergebnis nicht verändern) IIRC Die Gewerkschaft garantiert nicht, dass die zwei Mitglieder tatsächlich genau die gleichen Standorte teilen (Ausrichtung oder Größe der beiden Mitglieder könnten sich immer noch unterscheiden, genau wie in meinem Kurzkommentar) – joop

Verwandte Themen