Java Bitverschiebung kann mir jemand weiterhelfen?

mamnu

Cadet 4th Year
Dabei seit
Okt. 2017
Beiträge
119
int a=5;
int erg = a<< 1+1;

Warum kommt bei dieser Bit Operation 20, also in Bitdarstellung (10100) raus?

ich komme immer auf ein anderes Ergebnis nämlich (folgender Rechenweg)
5 ist in Bitdarstellung ja 101
als erstes wird ja das + ausgewertet also wird aus a<<1+1 ja a<<2
also werden ja dann die 101 (in Dezimal 5) um 2 nach linksverschoben
und wenn man die 101 um 2 nach linksverschiebt, dann müsste doch 100 in Bitdarstellung rauskommen und das wäre doch eine 4 in Dezimal
Kann mir jemand weiterhelfen wie man da auf eine 20 kommt?
Über Hilfe wäre ich dankbar
Ach, übrigens ich spreche hier von Java
 
Zitat von mamnu:
und wenn man die 101 um 2 nach linksverschiebt, dann müsste doch 100 in Bitdarstellung rauskommen und das wäre doch eine 4 in


Erkläre Mal deinen Gedankengang, ich kann ihn einfach nicht verstehen.

Dir müsste doch schon auffallen, dass du eine 1 zu wenig hast.
 
  • Gefällt mir
Reaktionen: BeBur
Hi,

du "schiebst", du addierst und subtrahierst nicht!

Beispiel: ich habe in Bitschreibweise deine "101". Jetzt mache ich "<<", also eine Linksverschiebung um zwei Positionen nach links. Das heißt, ich nehme meine rechte Hand, lege sie an die rechte "1" und drücke die "101" um zwei Stellen nach links, so dass "101" rechts um zwei Stellen erweitert wird, also "00" angefügt wird.

Die in dezimaler Schreibweise repräsentierten Werte sind hier erstmal völlig unerheblich! Was steht als "Bit" da, das wird verschoben, entweder nach Links oder Rechts. Das ist zumindest das, was ich in Java vor etlichen Zeiten mal gelernt habe.

Gegenbeispiel: du hast die "101" und verschiebst um zwei Stellen nach rechts, also ">>". Was kommt da raus?

Siehe auch: hier

VG,
Mad
 
  • Gefällt mir
Reaktionen: BAGZZlash
Zitat von mamnu:
und wenn man die 101 um 2 nach linksverschiebt, dann müsste doch 100 in Bitdarstellung rauskommen und das wäre doch eine 4 in Dezimal

Genau da ist der Fehler.
Die anderen habens ja schon erklärt.

Du solltest dir immer im klaren sein, wie groß dein Dateityp ist. Ein integer hat IMMER 32 bit. Dir steht also stets die volle Breite zur Verfügung.
Wenn du was schiebst, dann schiebst du deine 1en und 0en innerhalb dieser 32 bit hin und her. Abgeschnitten wird dann logischerweise erst wenn du das Ende erreicht hast und nicht schon nach drei bit.

In dem zuge kannste dich auch gleich mal mit overflow und signed/unsigned beschäftigen. Wobei ich grad nicht sagen kann obs das in Java in der Form gibt. Sollte aber zum Grundwissen gehören.
 
Also ich weiß ja nicht, wie das bei Java aussieht, aber in C (zumindest dem gcc) ist der Datentyp dem Bitshift Operator egal:
Code:
    # include <stdio.h>
          
    void main()
    {
    char test=1;
    printf("%d\n", test<<0);
    printf("%d\n", test<<1);
    printf("%d\n", test<<2);
    printf("%d\n", test<<3);
    printf("%d\n", test<<4);
    printf("%d\n", test<<5);
    printf("%d\n", test<<6);
    printf("%d\n", test<<7);
    printf("%d\n", test<<8);
    test = test<<7;
    printf("%d\n", test);
    test = test<<8;
    printf("%d\n", test);
    }
Wie man sieht, ergibt 1<<8 256 statt 0, obwohl char ja nur 8 bits hat (und da signed somit max 127 bzw. -128 ergeben kann) bzw. 1<<7 ergibt 128 statt -128. Aufpassen muss man dann höchstens mit dem internen Rückgabetyp des Operators. Da wäre ich mir jetzt nicht sicher, wie der Compiler das verarbeitet.
 
Zitat von simpsonsfan:
Aufpassen muss man dann höchstens mit dem internen Rückgabetyp des Operators.
Das ist der Knackpunkt. Würdest du das Ergebnis wieder im char speichern, käme der Überlauf zum Tragen. Ich mutmaße daher, dass char<<x vom Compiler intern einfach als integer interpretiert wird und eben nicht ebenfalls als char.
 
@Rajin Hast Recht, aus 'nem Shift mit char oder int kommt ein int raus, aus 'nem Shift mit nem long ein long.
Code:
    # include <stdio.h>
          
    void main()
    {
    char chr=1;
    int in=1;
    long lng =1;
    printf("%ld\n", (chr<<32)>>1);
    printf("%ld\n", (in<<32)>>1);
    printf("%ld\n", (lng<<32)>>1);
    printf("sizes: char %d int %d long %d", sizeof(chr), sizeof(in), sizeof(lng));
    printf("\nsize after shift: char %d int %d long %d", sizeof(chr<<1), sizeof(in<<1), sizeof(lng<<1));
    }
Wobei ich nicht ausschließen möchte, dass das compilerspezifisch ist und in Java sowieso anders aussehen kann.
 
Wurde zwar schon alles gesagt, aber ich zitiere mal noch eine offizielle Quelle:

The signed left shift operator "<<" shifts a bit pattern to the left, and the signed right shift operator ">>" shifts a bit pattern to the right. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand.

Und da wie gesagt byte sind 8Bit, Integer in Java 32Bit sind, naja - wie die anderen schon sagten. Wenn man das weiss ist es ja auch klar. Jetzt weisst du es. Ob du den Operator jemals nutzen wirst?
 
Werbebanner
Zurück
Top