Gelöst - 2 x 16 Bit Integer in 1 x 32 Bit Float konvertieren?



  • Hallo werte Gemeinde!

    Ich habe zwei 16 bit Ints die aber eine 32 bit float Zahl sein sollen. Also zum Beispiel:

    Bit 32 bis 1 ..................... int2 | int1:

    1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 0 | 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1

    Die obige Bitreihenfolge beschreibt die Zahl: -1.2345678

    In C++ stehen folgende Werte in den beiden Variablen:

    int2: 49054 und int1: 1617 wenn die obige Bitfolge als UNSINGED WORD gelesen wird

    Wer weiß, wie ich wieder die Zahl -1.2345678 aus den beiden Integerwerten zurückzaubern kann?

    Gruß, Matze



  • union
    {
      float m_F;
      struct
      {
        int16_t m_I1;
        int16_t m_I2;
      };
    };
    

    das duerfte ein verstaendlicher weg sein.



  • Danke, ich werds mal ausprobieren! 🙂



  • float erg;
    
    int a,b;
    
    ((int*)&erg)[0])=b;
    ((int*)&erg)[1])=a;
    


  • Äh, ok werd ich auch mal probieren. Danke!



  • Sorry Leute, aber so einfach funktionierts dann doch wohl nicht. 😞 Hier mal mein Code:

    void calculateFT(RobotState* state)
    {
    	union 
    	{ 
    		float myfloat;
    		struct 
    		{ 
    			int16_t state->int1; 
    			int16_t state->int2; 
    		};
    		state->erg = myfloat;
    	};
    }
    

    RobotState ist ein strukturierter Datentyp, die INTs stehen in

    RobotState ist, soll;

    ist.int1
    ist.int2
    ist.erg // hier soll dann die wiederhergestellte Gleitkommazahl drin stehen

    (ist) wird beim Funktionsaufruf calculateFT(&ist); übergeben



  • geht nicht ist keine fehlerbeschreibung. Versuchs mal so:

    float calculateFT(RobotState* state)
    {
        union
        {
            float myfloat;
            struct
            {
                int16_t l;
                int16_t h;
            };
        } temp;
        temp.l=state->int1;
        temp.h=state->int2;
        return temp.myfloat;
    }
    


  • Sorry, aber das haut irgendwie nicht hin.

    void calculateFT(RobotState* state)
    {
        union { float myfloat; struct { int l; int h; }; }temp; 
        temp.l = state->int1; 
        temp.h = state->int2;
        state->erg = temp.myfloat;
    }
    

    (void) soll so sein. Da int16_t in meiner Umgebung kein gültiger Datentyp ist, habe ich "l"(low) und "h"(high) als normale INT deklariert. Am Ende jedoch, kommt nicht das gewünschte Ergebnis heraus, leider.

    Bit 32 bis 1 ..................... int2 | int1:

    1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 0 | 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1

    Die obige Bitreihenfolge beschreibt die Zahl: -1.2345678



  • matze77 schrieb:

    S Da int16_t in meiner Umgebung kein gültiger Datentyp ist, habe ich "l"(low) und "h"(high) als normale INT deklariert.

    ist int bei dir 16bit? falls nicht, versuch mal short bzw unsigned short oder WORD wie du es anfangs meintest.



  • Au weia! Da hast Du mich eiskalt erwischt!

    Also die 2 x 16 Bit kommen in Wirklichkeit als LONG an. Das bedeutet ja nun, soweit ich das gelesen habe, dass es sich dann um 2 x 32 Bit handelt.

    Problem:

    Die beiden 16 Bit Werte, werden in LONG (32 Bit) umgewandelt und verschickt. Dann empfange ich die beiden 32 Bit Werte und muss diese nun in einen 32 Bit FLOAT zurückverwandeln. Uiuiui!!!

    kurz: 1 x 32 FLOAT -> 2 x 16 INT -> 2 x 32 LONG --- Ziel --->1 x 32 FLOAT

    Also ich probiers mal so:

    union { float myfloat; struct { long l; long h; }; }temp; 
        temp.l = state->long1; 
        temp.h = state->long2;
        state->erg = temp.myfloat;
    

    Ne, das klappt nicht. Mist!



  • matze77 schrieb:

    [cpp]
    union { float myfloat; struct { short l; short h; }; }temp;
    temp.l = state->long1;
    temp.h = state->long2;
    state->erg = temp.myfloat;
    [/cpp]

    Ne, das klappt nicht. Mist!

    wie ich schon sagte, mach short oder WORD daraus.



  • YEEHAW ! ! ! So klappts:

    union { float myfloat; struct { unsigned short l; unsigned short h; }; }temp; 
        temp.l=state->usishort1; 
        temp.h=state->usishort2;
        state->erg = temp.myfloat;
    

    Die Werte kommen zwar als LONG an aber ich schreibe sie in UNSIGNED SHORT Variblen, so das sie wieder 16 bittig sind. Danach werden aus 2 x 16 Bit UNSIGNED SHORT mit union 1 x 32 FLOAT gezaubert.

    Danke Leute!



  • Unions sind nicht für Umwandlungen geeignet. Wurde schon desöfteren im C++ Unterforum besprochen.



  • Es geht auch folgendermaßen:

    void calculateFT(RobotState* state)
    {
       int tmp;
    
       tmp = ((state->int2&0xffff) << 16) | (state->int1&0xffff);
       state->erg = *((float*) &tmp);
    }
    

    Hier braucht man kein UNSIGNED SHORT, sondern kann einfach INT für int1 und int2 benutzen.



  • für so etwas gibt es memcpy&co. Alles Andere ist so gut wie immer undefiniert und fliegt euch früher oder später um die Ohren - oder Compilerspezifisch, so wie diese lustigen anonymen structs.



  • camper schrieb:

    für so etwas gibt es memcpy&co.

    ist dafuer aber ein ziemlich perverser overhead.

    Alles Andere ist so gut wie immer undefiniert und fliegt euch früher oder später um die Ohren - oder Compilerspezifisch, so wie diese lustigen anonymen structs.

    naja, anonym muessen die nicht sein, in (iso) c war casting eigentlich nur mittels unions moeglich.
    deswegen, wenn man sicher gehen will, named unions+structs 😉


Anmelden zum Antworten