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
 

Old Knitterhemd

Commander
Dabei seit
Jan. 2016
Beiträge
2.296

Madman1209

Fleet Admiral
Dabei seit
Nov. 2010
Beiträge
25.385
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
 

ReIex

Ensign
Dabei seit
Juni 2019
Beiträge
222
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.
 

simpsonsfan

Commander
Dabei seit
Feb. 2008
Beiträge
2.850
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.
 

Raijin

Fleet Admiral
Dabei seit
Nov. 2007
Beiträge
10.645

simpsonsfan

Commander
Dabei seit
Feb. 2008
Beiträge
2.850
@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.
 

abcddcba

Commander
Dabei seit
Juni 2018
Beiträge
2.101
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?
 
Top