unsigned char in unsigned long und zurück



  • Hallo!

    Mit folgendem Code kann ich einen u-long in einen u-char und zurück konvertieren. (Nicht die "Zahlenwerte" wie atol, ltoa).

    inline unsigned long __fastcall UCharToULong  (unsigned char pBuf[4])
    {
        return (pBuf[0] << 24 | pBuf[1] << 16 | pBuf[2] << 8 | pBuf[3]);
    }
    
    inline char * __fastcall ULongToUChar (unsigned long lVal, unsigned char pBuf[4])
    {
        pBuf[0] = (unsigned char) ( lVal  >> 24 )  & 0xff;
        pBuf[1] = (unsigned char) ( lVal  >> 16 )  & 0xff;
        pBuf[2] = (unsigned char) ( lVal  >>  8 )  & 0xff;
        pBuf[3] = (unsigned char)   lVal           & 0xff;
    
        return pBuf;
    }
    

    Der Code funktioniert wunderbar. Doch verstehe ich "ihn" nicht wirklich. Könnte mir wohl jemand erklären warum genau diese Bitoperationen nötig sind und/oder woher man so etwas weiß?
    Kann der Code unter Umständen Probleme machen (Ich meine keine Platformschwierigkeiten wo ein long z.b. != 4 Bytes und/oder ein char != 1 Byte ist)?

    Gruß Ulrich



  • Beim ersten werden die chars erst implizit nach unsigned long konvertiert dann geshiftet, so dass die bits an der richtigen stelle stehen und danach mittels bitweisem oder zu einem einziegen unsigned long.
    Am anfang siet das vielleicht so aus:

    pBuf[0]:
        00101110
    pBuf[1]
        11010001
    pBuf[2]
        10010110
    pBuf[3]
        00100101
    

    Wenn die jetzt implizit nach unsigned long gecasted werden, wird einfach vorne mit Nullen aufgefüllt, sie sehen jetzt so aus:

    pBuf[0] als unsigned long:
        00000000000000000000000000101110
    pBuf[1] als unsigned long
        00000000000000000000000011010001
    pBuf[2] als unsigned long
        00000000000000000000000010010110
    pBuf[3] als unsigned long
        00000000000000000000000000100101
    

    Danach werden die unsigned longs unterschiedlich weit geshiftet:

    pBuf[0] als unsigned long << 24:
        10111000000000000000000000000000
    pBuf[1] als unsigned long << 16
        00000000110100010000000000000000
    pBuf[2] als unsigned long << 8
        00000000000000001001011000000000
    pBuf[3] als unsigned long
        00000000000000000000000000100101
    

    Jetzt mittels bitweisem oder verknüpfen: die bits von zwei unsigned longs werden verglichen, wenn von 2 "parallelen" bits eins gesetzt ist, ist es auch im Ergebnis gesetzt:

    Ergebnis:
        10111000110100011001011000100101
    

    (kann sein, dass ich mit den bits jetzt was durcheinander gehauen hab...
    Zurück gehts genau andersrum...



  • Ulli schrieb:

    Mit folgendem Code kann ich einen u-long in einen u-char und zurück konvertieren.

    Nicht ganz. Erstens hast du hier ein unsigned char Array, das ist schon ein Unterschied. Und zweitens wird hier nicht konvertiert, sondern vielmehr die Reihenfolge umgedreht.

    Ulli schrieb:

    Kann der Code unter Umständen Probleme machen

    Ausser Plattform spezifischen Sachen eigentlich nicht.
    Du solltest aber darauf achten, ein 'unsigned char*' in ULongToUChar zurückzugeben, wenn du schon ein solches Array als Parameter übergibst.


Anmelden zum Antworten