float in hex umwandeln



  • Gehen tut das schon, es ist nur nicht unbedingt üblich. Man muss eben als Basis 16 nehmen. C bietet ja Gleitkomma Literale in hexadezimaler Darstellung an. Das sieht dann zB so aus

    0x1.fffffp+127f
    

    Wobei hier der Exponent in dezimal Form vorliegt. Diesen ebenfalls umzuwandeln, sollte aber nicht das Problem sein.
    Ich glaube aber nicht, dass es das ist, was der OP beabsichtigt. Daher, Problembeschreibung genauer formulieren, und dann sehen wir weiter.



  • Also ich benutze VC++.NET und lese über ein Editfeld Werte ein.
    Diese Werte sind vom Typ float und sollen in eine Hexzahl umgewandelt werden um sie über die serielle Schnittstelle an ein Messgerät zu senden.
    Insgesamt gibts 18 Werte einzulesen, umwandeln und an Gerät zu senden.
    Bsp.: ich lese fDaempfung = 0.2 ein, in Hex wäre das 3E 4C CC CD, also 4 Byte lang. Diese Bytes möchte ich dann in einem Array speichern.

    BYTE hex[20][4];
    BYTE Message4[i][4] ={hex[i][0], hex[i][1], hex[i][2], hex[i][3]};
    
    for(int i=0; i<18; i++)
    {
     MyCOM.WriteNBytes(4, (BYTE*) &Message4[i]);
    }
    

    So hab ich mir das gedacht!!



  • Achso, du willst die Binärcodierung der float-Zahl in ein BYTE-Array packen, richtig? Das könntest du z.B. per reinterpret_cast und memcpy machen:

    float zahl;
    BYTE data[sizeof(float)];
    memcpy(data,reinterpret_cast<BYTE*>(&zahl),sizeof(float));
    


  • Danke CStoll, ich werde das mal ausprobieren!!



  • So hab ne Lösung gefunden.
    Für diejenigen die es interessiert:

    union Float2Hex
    {
     float fValue;
     BYTE Hex[4];
    };
    
    Float2Hex MyVariable;
    
    MyVariable.fValue = irgendeinWert;
    
    MyVariable.Hex[0] = irgendeinWertInHex;
    MyVariable.Hex[1] = irgendeinWertInHex;
    MyVariable.Hex[2] = irgendeinWertInHex;
    MyVariable.Hex[3] = irgendeinWertInHex;
    

    Funktioniert so da bei Union im gegenteil zu Struct alle Variablen in
    gleicher Speicheradresse abgelegt werden.
    Dann einfach überschreiben.



  • "Hex Werte" sind es zwar immer noch nicht, aber auch wenn es so funktionieren sollte, Unions sind für sowas eigentlich nicht konzipiert. Verwende besser die Lösung von CStoll. Du kannst sogar einfach nur einen Cast verwenden, sofern eine Kopie nicht erforderlich ist

    float zahl;
    BYTE* data = reinterpret_cast<BYTE*>(&zahl);
    sende_seriell(data, sizeof(float));
    


  • Was sollen es denn sonst für werte sein, wenn keine Hexadezimal-Werte?
    Was spricht denn gegen diese Lösung?
    Für was sind denn Unions gemacht?



  • maRKus23 schrieb:

    Was sollen es denn sonst für werte sein, wenn keine Hexadezimal-Werte?

    Binärwerte (der Computer rechnet intern NUR mit Binärzahlen).



  • Schon klar das der Computer mir binären Werten rechnet, doch für den Anwender werden sie jawohl mit der Basis 16 dargestellt.



  • Nicht unbedingt - wie sie für den Anwender dargstellt werden, bestimmst du (und wenn du nichts dazusagst, stellt C++ ein char-Array* normalerweise als ASCII-String dar)

    * und BYTE ist idR ein typedef für 'unsigned char'



  • maRKus23 schrieb:

    Was sollen es denn sonst für werte sein, wenn keine Hexadezimal-Werte?

    Werte sind Werte, sonst nichts. Sprich, auf Datenebene einfach eine Ansammlung von Bits. Und auch nur diese werden in Variablen gespeichert. Wie du diese Werte letztendlich darstellst, also dir anzeigen lässt, ist davon vollkommen unabhängig. Das kann hexadezimal, dezimal oder binär sein. Oder du verwendest irgendwelche Symbole. Das ist auf Datenebene vollkommen belanglos.

    maRKus23 schrieb:

    Für was sind denn Unions gemacht?

    Unions sind dafür gedacht, dass sich mehrere Objekte den gleichen Speicher teilen. In deinem Code wird das "missbraucht", um frei von jeglicher Semantik, einen Typ auf einen anderen abzubilden. Das funktioniert zwar oftmals aufgrund gewisser Gegebenheiten, wie zB Alignment. Verstösst aber gegen den Grundsatz, dass du bei einer Union nur auf das Element lesend zugreifen solltest, welches zuletzt geschrieben wurde.

    maRKus23 schrieb:

    Schon klar das der Computer mir binären Werten rechnet, doch für den Anwender werden sie jawohl mit der Basis 16 dargestellt.

    Du beantwortest es dir ja schon selbst, hexadezimal (Basis 16) ist eine Form der Darstellung. BYTE, oder welcher Typ auch immer, bleibt trotzdem lediglich eine Ansammlung von Bits, welche auf Sprachebene zu etwas definiert werden, wie zB 'vorzeichenlose Ganzzahl der Grösse sizeof(T)'.



  • Naja, da habt ihr wohl doch recht was die Hex-Werte angeht.
    Vielen Dank für eure Hilfe!! :xmas2:



  • Ähm union ist ja gut und schon... nur...

    Float _so_ umzuwandeln bzw. auszulesen ist doch *falsch*, denn da liegt dann nicht der wirkliche Kommawert drin.

    In einer Float wird im ersten Byte (mal grob umrissen) das Komma abgespeichert (also wo sich das Komma in der noch folgenden Zahlenreihe befinden soll).

    In den nachfolgenden Bytes befinden sich dann erst die Werte - aber - auch die sind (wie auch das Komma darselbst) nicht ganz 1:1 abgespeichert (da wird erstens angenommen, dass der erste (nicht abgespeicherte) Bitwert 1 ist und es gibt noch eine Fehlerbereinigung. Also eine Float *so* auszulesen ergibt alles - aber niemals den Wert, den man eigentlich auslesen wollen würde...


Anmelden zum Antworten