Zwei 1 Byte Werte in einer 2 Byte Variable speichern



  • Hallo,

    ich möchte zwei zwei 1 Byte Werte in einer 2 Byte Variable speichern,
    der eine Wert soll in den oberen 8 Bit gespeichert werden, der Andere
    in den unteren 8 bit.
    Ich denke das geht irgendwie mit Bit-Shifting Operationen aber wie
    genau das weiß ich noch nicht. Jemand eine Idee?

    🙂


  • Mod

    Ganz einfach: Die eine Variable shiftest du um 8 Bits nach links (mit <<8) und die andere nicht. Das Ergebnis addierst du. Ob mittels logischem OR oder mathematischem + ist dabei egal. Dies ist der Wert den du deiner 2 Byte Variable zuweist.



  • Edit: Müll.
    Jaja, janjan. Kein Grund gleich zynisch zu werden 🙂
    Man wird doch wohl noch Fehler machen dürfen (auch wenn dieser hier zugegebenermaßen zu der peinlicheren Sorte gehört.)
    Und und Oder vertauscht, und in die falsche Richtung geshiftet. 🤡

    Danke auf jeden Fall, dass du das in deinem Quote festgehalten hast.



  • Cox schrieb:

    short foo(char c1, char c2)
    {
        return c1 & (c2 >> 8);
    }
    

    Aufgabe vorgekaut und dann auch noch falsch. Gratuliere.



  • Danke fuer die Information. Ich glaube es klappt so habe
    ich es jetzt gemacht:

    short var = 0;
    char  var1 = 100;
    char  var2 = 200;
    var = var1 | ( var2 << 8);
    

    Gibt es eine Möglichkeit das zu verifizieren ?



  • Klar, geh den Weg rückwärts und guck, ob die Eingangsdaten dabei herauskommen.
    Kannst dir auch noch ´nen Test bauen, der die Konvertierung aller möglichen 65K Kombinationen durchrechnet und gegenprüft.



  • Gib dir den Wert halt in binär oder hexadezimal aus. Aber um es dir zu ersparen: es ist richtig.



  • In wie weit ist eigentlich die Größe eines chars (oder der eingebauten Typen generell) vom Standard festgelegt?
    Anders gefragt: Ist diese Methode portabel?



  • In der Regel ist es portabel auf den meisten Systemen, jedoch nicht 100 %.

    Zum einen, wird nicht bedacht, dass ein byte mehr als 8 bit haben kann (oder weniger), also ist ein shiften um 8 falsch. Du bedenkst außerdem nicht, dass ein short auch nur 1 byte groß sein kann, also passt deine Datenmenge gar nicht in den Typ. Zu guter letzt ignorierst du jeglichen Aspekt der Endianess, sodass deine Shift-Richtung falsch sein kann.

    Ein char ist übrigens definiert genau 1 byte groß. Nicht jedoch 8 bit.



  • Mir ist klar wie ich an den zweiten Wert komme:

    cout << (var >> 8);
    

    Aber wie komme ich an den ersten?



  • Binäre und-Verknüpfung.

    Google mal nach Binäroperationen.



  • Janjan schrieb:

    Zum einen, wird nicht bedacht, dass ein byte mehr als 8 bit haben kann (oder weniger), also ist ein shiften um 8 falsch.

    Dann versuchs mit int. int hat auf jeder Plattform mindestens 16 bits.
    Zum Kodiern und Dekodieren:

    int zusammenfuegen (char a, char b) {
       int c = a;
       return (c << 8) | b;
    }
    
    int trennen (int c, char &a, char &b) {
       a = (c >> 8) & 0xff;
       b = c & 0xff;
    }
    

    Ich habe es nicht getestet, aber ungefähr so sollte es klappen.


  • Mod

    Und char ist mindestens 8 Bit laut Standard. Darf aber natürlich länger sein.



  • SeppJ schrieb:

    Und char ist mindestens 8 Bit laut Standard. Darf aber natürlich länger sein.

    Ich verwende char so gut wie garnicht mehr. Außer für Zeichen bzw. Zeichenketten (char* oder const char*).



  • ShortIstMord schrieb:

    short var = 0;
    char  var1 = 100;
    char  var2 = 200;
    var = var1 | ( var2 << 8);
    

    Du musst hier darauf aufpassen, dass char ein vorzeichenbehafteter Typ sein kann. Bei vorzeichenbehafteten 8bit-chars kann die Zahl 200 nicht dargestellt werden. Der Wert von var2 wäre dann implementierungsabhängig. Eine Reinterpretation der unteren 8 Bits angenommen, würde var2 den Wert -56 speichern. Bevor die Bitoperationen (<<, |) angewendet werden, findet eine "integral promotion" statt. Das heißt, var1 und var2 werden zu zwei int-Werten konvertiert. Auf der Linken Seite von << steht ein potentiell negativer Wert. Bitoperationen (inklusive <<) auf negativen Zahlen ist wieder implementierungsabhängig....

    Also, wenn Du Glück hast, passiert genau das, was Du willst. Das ist aber nicht garantiert.

    Guck mal hier: http://jk-technology.com/c/inttypes.html



  • krümelkacker schrieb:

    Bei vorzeichenbehafteten 8bit-chars kann die Zahl 200 nicht dargestellt werden. Der Wert von var2 wäre dann implementierungsabhängig. Eine Reinterpretation der unteren 8 Bits angenommen, würde var2 den Wert -56 speichern.

    Genauer: "unter der Annahme des Zweierkomplements und der Reinterpretation der Bits". Das Zweierkomplement ist zwar sehr populär, aber nicht vom C++ Standard vorgeschrieben.



  • Janjan schrieb:

    Zu guter letzt ignorierst du jeglichen Aspekt der Endianess, sodass deine Shift-Richtung falsch sein kann.

    Selten so einen Unfug gelesen...



  • Tim schrieb:

    Janjan schrieb:

    Zu guter letzt ignorierst du jeglichen Aspekt der Endianess, sodass deine Shift-Richtung falsch sein kann.

    Selten so einen Unfug gelesen...

    Ja sicher... Hast du noch nie das Problem gehabt, dass die Beispiele
    in den Bücher mit Shiften anstelle einer Multiplikation mit
    2^n nicht funktionierten, weil die Endianess nicht berücksichtigt wurde... 🙄



  • Braun-Bär Bruno schrieb:

    Tim schrieb:

    Janjan schrieb:

    Zu guter letzt ignorierst du jeglichen Aspekt der Endianess, sodass deine Shift-Richtung falsch sein kann.

    Selten so einen Unfug gelesen...

    Ja sicher... Hast du noch nie das Problem gehabt, dass die Beispiele
    in den Bücher mit Shiften anstelle einer Multiplikation mit
    2^n nicht funktionierten, weil die Endianess nicht berücksichtigt wurde...

    Nein, Tim hat recht. Ein links-shift um 1 entspricht immer einer Multiplikation mit 2. Das gilt für alle ganzzahligen Typen (char, short, int, long, ...) und deren vorzeichenlose Verwandten. Es spielt absolut keine Rolle, in welcher Reihenfolge die Bytes gespeichert werden.



  • Z schrieb:

    Nein, Tim hat recht. Ein links-shift um 1 entspricht immer einer Multiplikation mit 2. Das gilt für alle ganzzahligen Typen (char, short, int, long, ...) und deren vorzeichenlose Verwandten.

    1. Shifts auf negativen Zahlen sind implementierungsabhängig.
    2. Du tust so, als sei char vorzeichenbehaftet. char kann aber auch vorzeichenlos sein. Du weißt, dass es 3 char-Typen gibt, ja? char, signed char und unsigned char. Ob sich char sowie signed char oder wie unsigned char "verhält" (wertebereichstechnisch) ist nicht festgelegt.


Log in to reply