warum ist 1>>32 == 1?

Lesezeit: 3 Minuten

Ich frage mich, ob dies vielleicht ein JVM-Fehler ist?

Java-Version “1.6.0_0” OpenJDK-Laufzeitumgebung (IcedTea6 1.4.1) (6b14-1.4.1-0ubuntu13) OpenJDK 64-Bit-Server-VM (Build 14.0-b08, gemischter Modus)

class Tmp {
    public static void main(String[] args) {
        System.out.println("1>>1 = "+(1>>1));
        System.out.println("1>>2 = "+(1>>2));
        System.out.println("1>>31 = "+(1>>31));
        System.out.println("1>>32 = "+(1>>32));
        System.out.println("1>>33 = "+(1>>33));
    }
}

erzeugt dies, wenn ich es ausführe:

1>>1 = 0
1>>2 = 0
1>>31 = 0
1>>32 = 1 <---------- should be 0 i think
1>>33 = 0

Ich erhalte auch die gleichen Ergebnisse für jedes Vielfache von 32.

muss ich meine eigene Rechtsverschiebung schreiben, um dies zu überprüfen?

  • bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/601266 Bitte halte uns (auf SO) auf dem Laufenden.

    – rwong

    3. Juli ’10 um 5:30

  • re @ Arthur: Scheint ja, Sie müssen Ihre eigene Rechtsverschiebung schreiben, um dies zu überprüfen.

    – rwong

    3. Juli ’10 um 5:39

  • rwong: das ist mein Fehler, ich werde ihn löschen. Dies ist kein Compiler-Fehler, obwohl ich immer noch denke, dass es “falsche Mathematik” ist.

    – Arthur Ulfeldt

    3. Juli ’10 um 5:41

  • Siehe auch Was ist der Grund, warum Hochsprachen wie C#/Java den Bitverschiebungszähler-Operanden maskieren?

    – Matthew Flaschen

    3. Juli ’10 um 5:48


  • +1 Danke für die Frage, wusste das noch nie. 🙂

    – sarnold

    3. Juli ’10 um 6:26

warum ist 132 1
rwong

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.22.1

15.19 Schichtführer

Wenn der hochgestufte Typ des linken Operanden ist int, nur die fünf niederwertigsten Bits des rechten Operanden werden als Verschiebeweg verwendet. Es ist, als ob der rechte Operand einem bitweisen logischen UND-Operator unterzogen würde & (§15.22.1) mit dem Maskenwert 0x1f. Der tatsächlich verwendete Schaltweg liegt daher immer im Bereich von 0 bis einschließlich 31.

Wenn der hochgestufte Typ des linken Operanden ist lang, dann nur die sechs niederwertigsten Bits des rechten Operanden werden als Verschiebeweg verwendet. Es ist, als ob der rechte Operand einem bitweisen logischen UND-Operator & (§15.22.1) mit der Maskenwert 0x3f. Der tatsächlich verwendete Schaltweg liegt daher immer im Bereich von 0 bis einschließlich 63.

(Hervorhebung von mir)

1641803787 657 warum ist 132 1
amara

Es ist kein Fehler. In n >> m, es betrachtet nur die letzten fünf Bits von m – jede Zahl größer als 31 wird also auf diese Zahl mod 32 reduziert. (256 >> 37) == 8 ist wahr.

Bearbeiten: Dies gilt, wenn Sie mit ints arbeiten. Wenn es lang ist, dann sieht es zuletzt aus sechs Bits von m oder Mods von 64.

  • Aus (1 >> 32) wird also (1 >> 0)? Seltsam.

    – egrunin

    3. Juli ’10 um 5:32

  • +1. Vielleicht möchten Sie JLS zitieren §15.19.

    – Matthew Flaschen

    3. Juli ’10 um 5:34

  • Ein bisschen traurig darüber. Warum hat Java es so definiert? Ich dachte, C++ hat tatsächlich zusätzliche Schritte (CPU-Anweisungen) unternommen, um sich darum zu kümmern. Die Entscheidung scheint von jahrzehntealten Mikroprozessoren abzustammen.

    – rwong

    3. Juli ’10 um 5:37

  • @rwong, schon wieder falsch. C++ sagt: “Das Verhalten ist undefiniert, wenn der rechte Operand negativ oder größer oder gleich der Länge in Bits des heraufgestuften linken Operanden ist.” Das heißt, wenn Sie (1 >> 33) tun, öffnen Sie sich für nasale Dämonen. Java ist weitaus spezifischer als C++, nicht weniger.

    – Matthew Flaschen

    3. Juli ’10 um 5:42


  • Ich dachte (-9 % 9) == 4 wäre in C++ schon seltsam genug. (Ich kenne den Grund, aber es war trotzdem amüsant)

    – rwong

    3. Juli ’10 um 5:52

.

287010cookie-checkwarum ist 1>>32 == 1?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy