Zwei 1 Byte Werte in einer 2 Byte Variable speichern



  • 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.



  • short x;
    char a=56,b=199;
    char* p = (char*) &x;
    x[0]=a;
    x[1]=b;
    

    Ohne Garantie 😉 *scnr*



  • krümelkacker schrieb:

    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.

    Probier mal das mit allen Compilern, die Dir zur Verfügung stehen:

    int main()  {
       char a = -3;
       signed char b = -3;
       unsigned char c = 3;
       printf ("%d %d %d\n", a<<1, b<<1, c<<1);  
    }
    

    Du bekommst immer -6, -6 und 6. Wollen wir wetten? 😉



  • Sorry...

    Hab wohl den falschen Smilie genommen...
    Das sollte ironisch sein...



  • Braun-Bär Bruno schrieb:

    Hab wohl den falschen Smilie genommen...
    Das sollte ironisch sein...

    Natürlich. Und der Text sollte eigentlich ein Geburtstagsgruß an Deine Großmutter werden. 😃


Anmelden zum Antworten