Announcement

Collapse
No announcement yet.

seltsames Verhalten des Schiebeoperators

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • seltsames Verhalten des Schiebeoperators

    Hallo,

    ich habe in einem Programm die Bitrotation verwendet, mit zwei Implementierungs-Alternativen:
    Code:
    inline unsigned rotl (unsigned a, unsigned b) {
       return a << b | a >> 32-b;
    }
    inline unsigned rotl2 (unsigned a, unsigned b) {
       return a << b | a >> -b;
    }
    rotl scheint richtig zu funktionieren, aber rotl2 nicht. Nach etwas Probieren habe ich das Problem auf folgendes reduziert:
    Code:
    cout << (215428749u >> -15u) << endl;
    Dieser Code gibt seltsamerweise 0 aus!

    Liegt das an einem Fehler des Compilers (MS Visual Studio 2008, Ver. 9.0.30729.1 SP), oder ist vielleicht das Resultat der Verschiebung implementierungsabhängig, wenn der Wert des rechten Operanden nicht im Bereich 0 .. 31 ist? Soviel ich weiß, wird der rechte Operand immer modulo 32 genommen (oder genauer: modulo der Bitlänge des linken Operanden) und es müsste hier also um 17 nach rechts geschoben werden...

    Ich habe jetzt auch die Funktionen _rotl und _rotr in stdlib.h gefunden, die man für diesen Zweck verwenden kann, aber ich wüsste trotzdem gern, warum dieses a >> -b nicht wie gedacht funktioniert.

  • #2
    Alle Operatoren in C/C++ unterliegen einer Wertigkeit ihrer Abarbeitung.
    Steht in der Hilfe.
    << und | sind gleichwertig. Tja, was macht der compiler nun?
    Erst Oder verknüpfen und dann schieben ? Heute so und morgen eben anders.

    (a << b) | (a >> -b);

    mfg
    Fred

    Comment


    • #3
      Nein. << hat höheren Vorrang als | und die Klammern sind redundant.

      Außerdem ist die Frage, warum (215428749u >> -15u) nicht das erwartete Ergebnis liefert.

      Comment


      • #4
        Was mach ein negativer unsigend Wert für einen Sinn?

        Ich bekomme übrigens 1643 als Ergebnis....

        Bild1.jpg
        Zuletzt editiert von Christian Marquardt; 22.08.2011, 16:13.
        Christian

        Comment


        • #5
          Ja, und ich bekomme 0 als Ergebnis. Und das sollte nicht sein.

          Der Fehler trat ja ursprünglich bei der Rotation a << b | a >> -b auf, mit beiden Operanden unsigned, und 15u habe ich als beispiel für b eingesetzt.

          Inzwischen habe ich mein altes C-Buch wieder ausgegraben, da steht im Anhang: das Resultat der Verschiebung ist undefiniert, wenn der Wert des rechten Operanden negativ oder nicht kleiner als die Bitlänge des linken Operanden ist.

          Damit habe ich nicht gerechnet. Das ist also ein weiteres Schlupfloch, um Code mit undefiniertem Laufzeitverhalten zu schreiben...

          Comment

          Working...
          X