Frage zur Umwandlung von 32 Bit Zahlen in 64 Bit Zahlen im Hinblick auf Endianess



  • Hallo,
    gegeben seien 2 32 Bit Zahlen. Diese sollen in eine 64 Bit Zahl umgewandelt werden. (Ja, ich weis, ich könnte natürlich einfach shift benutzen, ich will aber folgenden code verwenden)

    unsigned int Low;
    unsigned int High;
    
    unsigned int arr[2];
    
    #ifdef LITTLE //little endian wird benutzt
    arr[0] = High;
    arr[1] = Low;
    #elif BIG //big endian wird benutzt
    arr[0] = Low;
    arr[1] = High;
    #endif
    
    unsigned long long uint64;
    memcpy(uint64, arr, sizeof(unsigned long long));
    

    Ist das so korrekt (wenn man Middle Endian jetzt mal rauslässt)?



  • ich will ich will ich will
    wieso willst du das?
    hat nur nachteile.



  • mir ist klar, dass

    typedef unsigned long long ull;
    ull x = (static_cast<ull>(High)<<32) | Low;
    

    einfacher/performanter/portabler ist. ICh wollte nur wissen, ob mein Code von oben so korrekt ist (es geht mir in erster Linie um das Verständnis von Endianess)



  • ok.
    du hast die endianness genau vertauscht.

    little endian fängt bei adresse 0 mit dem least-significant-byte an. d.h. du musst auch in arr[0] den "low" teil reinschreiben. also genau verkehrt rum.

    natürlich setzt es er weitere dinge voraus, wie z.b. dass "long long" genau doppelt so gross ist wie "int". das ist nicht garantiert, aber WENN es so ist (und oft ist es so), dann müsste dein code IMO passen.

    einfaches beispiel, (mit 32 bit):

    gegeben sei die zahl 0x12345678

    little endian (z.B. x86) legt die so in den speicher:

    adresse   0     1     2     3
            0x78, 0x56, 0x34, 0x12
            low ------------> high
    

    und big endian (z.B. 68k) legt die so in den speicher:

    adresse   0     1     2     3
            0x12, 0x34, 0x56, 0x78
            high <------------ low
    

    wenn du nun den 0x1234 (high) und den 0x5678 (low) teil in getrennten variablen hast, dann musst du natürlich bei little endian den low teil zuerst schreiben, und dann erst den high teil.



  • Schon mal ueber union nachgedacht:

    union Whatever
    {
      uint_64 i64;
      uint_32 a32[2];
    };
    

    Dabei kannst du dann deine 64 Bit Zahl zuweisen und die einzelnen Array-Elemente als 32 Bit Zahl auslesen. Ob die Varianten mittels memcpy oder static_cast + shift schneller sind, wage ich zu bezweifeln.



  • static_cast + shift ist mit an sicherheit grenzender wahrscheinlichkeit die schnellste variante.


Anmelden zum Antworten