Integer in 4 Bytes zerlegen - Wie?



  • Tachyon schrieb:

    val & 0xFF liefert hingegen immer DD. Egal ob Little- oder Big Endian.
    Soll heißen: Mit der Bitshift Methode lässt sich ein int plattformunabhängig serialisieren. Irgendwelche Overlays sind hingegen (logischerweise) "Implementation dependent". Und die Sache mit der Union ist so ein Overlay.

    Nur was wenn ich val vorher 24bits nach rechts schiebe?

    Wenn ich AA BB CC DD um 24 bit nach rechts verschiebe habe ich ja
    00 00 00 AA

    Wenn ich aber DD CC BB AA um 24bit nach rechts verschiebe habe ich
    00 00 00 DD

    wenn ich
    val & 0xFF mache, dann weiss ich ja dennoch nicht in welchem byte nun der interessante wert steht...



  • Ich vermute, daß der Shift - Operator >> eben nicht 'nach rechts' verschiebt, sondern 'in Richtung LSB', rein physikalisch also auf einem Little Endian System anders, als auf einem Big Endian System.



  • Belli schrieb:

    Ich vermute, daß der Shift - Operator >> eben nicht 'nach rechts' verschiebt, sondern 'in Richtung LSB', rein physikalisch also auf einem Little Endian System anders, als auf einem Big Endian System.

    macht natürlich sinn. danke.



  • Shade Of Mine schrieb:

    Nur was wenn ich val vorher 24bits nach rechts schiebe?

    Wenn ich AA BB CC DD um 24 bit nach rechts verschiebe habe ich ja
    00 00 00 AA

    Wenn ich aber DD CC BB AA um 24bit nach rechts verschiebe habe ich
    00 00 00 DD

    wenn ich
    val & 0xFF mache, dann weiss ich ja dennoch nicht in welchem byte nun der interessante wert steht...

    🙄

    val = 0xAABBCCDD; 
          val >>= 24;
          // val == 0xAA
    


  • Also, vielen Dank erstmal für eure zahlreichen Antworten!

    Habe das ganze jetzt mehr oder weniger am laufen: Ich splitte den Integer jetzt so:

    int x, x_1, x_2, x_3, x_4;
    
    x_4 = a & 0xff; 
    x_3 = ( a >> 8 ) & 0xff;
    x_2 = ( a >> 16) & 0xff;
    x_1 = ( a >> 24) & 0xff;
    
    x=x_1+256*x_2+(x_3+256*x_4)/65536;
    

    x ist dann die endgültige X-Koordinate. Das funktioniert soweit auch wunderbar, doch gibt es einen Fehler:

    Als ich meine ersten 8 Vertices ausgelesen habe, hatte der erste folgende Koordinaten: 10, 10, 246
    Korrekt wäre aber: 10, 10, -10

    Sprich: es gibt Probleme, sobald eine negative Zahl auftritt. Der gesplittete Integer sieht dabei so aus:

    x_1=246, x_2=0, x_3=0, x4=0

    Scheint also ein Fehler beim splitten zu sein.
    Was ist hier falsch?



  • Die negativen Zahlen kannst Du z.B. so holen:

    x_4 = (int)(char)(a & 0xff); 
    x_3 = (int)(char)(( a >> 8 ) & 0xff); 
    x_2 = (int)(char)(( a >> 16) & 0xff); 
    x_1 = (int)(char)(( a >> 24) & 0xff);
    

    😉



  • Danke Dir! Es funktioniert 😃



  • Ich glaube, ob char signed ist ist abhängig von der Implementierung. Schreib (signed char) , dann bist du auf der sicheren Seite.



  • In C++ noch static_cast verwenden, und dann ist man schon nahe an der Perfektion. 🙂



  • Nexus schrieb:

    In C++ noch static_cast verwenden, und dann ist man schon nahe an der Perfektion. 🙂

    warum? der c-cast macht doch hier nix anderes.
    ich schlage mal den c++-cast vor:

    x_3 = int(char( (a>>8)&0xff) ));
    

    ps: ich mag static_cast nicht und benutze ihn eigentlich nur für downcasts in der klassenhierarchie.



  • Den C++-Function-Style-Cast sieht man auch sehr selten.

    Ich bevorzuge static_cast , weil der sicherer ist und ich sehe da schneller, was getan wird. Die Länge des Schlüsselwortes nehme ich dafür in Kauf. Die Diskussion hatte ich aber schon ein paar Mal. Schlussendlich ists wie so oft auch ein wenig Geschmackssache...


Anmelden zum Antworten