Perbedaan antara >>> dan >>

Jawaban:

408

>> apakah aritmatika bergeser ke kanan, >>> adalah pergeseran logis yang benar.

Dalam pergeseran aritmatika, bit tanda diperpanjang untuk menjaga keabsahan nomor tersebut.

Sebagai contoh: -2 direpresentasikan dalam 8 bit adalah 11111110(karena bit yang paling signifikan memiliki bobot negatif). Menggesernya sedikit dengan menggunakan pergeseran aritmatika akan memberi Anda 11111111, atau -1. Pergeseran kanan logis, bagaimanapun, tidak peduli bahwa nilainya mungkin mewakili angka yang ditandatangani; itu hanya memindahkan segalanya ke kanan dan mengisi dari kiri dengan 0s. Menggeser -2 bit kanan kita dengan menggunakan shift logis akan memberi 01111111.

danben
sumber
8
Sementara saya setuju dan menghargai bahwa perubahan aritmatika dapat digunakan untuk melipatgandakan angka yang ditandatangani 2^k, saya merasa aneh bahwa ini adalah jawaban semua orang. String bit bukan angka, dan >>selalu dapat digunakan pada string bit apa pun: string selalu melakukan hal yang sama terlepas dari peran string yang dimainkan bit dan terlepas dari apakah itu memiliki konsep 'tanda'. Apakah tidak apa-apa untuk memperluas jawaban Anda yang sudah bagus dengan diskusi tentang kasus ketika operan Anda tidak ditafsirkan sebagai nomor yang ditandatangani? Apakah keluhan saya masuk akal?
Ziggy
11
Mengapa Anda mengatakan string bit bukan angka? Apakah Anda mengatakan urutan angka desimal bukan angka?
danben
4
@danben Membahas apakah angka atau bukan hanya masuk akal jika Anda menautkannya ke suatu konteks. Jika internet hanya listrik, maka saya setuju bahwa sebuah String hanyalah angka.
bvdb
1
@danben tetapi sebenarnya, saya pikir apa yang sebenarnya dimaksud Ziggy (imho), adalah bahwa a Stringjuga dapat dianggap sebagai a char[]. Dia tidak mengatakan bahwa a charbukan angka; dia hanya mengatakan bahwa itu nomor yang tidak ditandatangani . Saya pikir di situlah dia tersesat.
bvdb
5
@ Ziggy benar: Tidak setiap string bit adalah angka, dan tidak setiap urutan angka desimal adalah angka. Sebagai contoh: Nomor telepon, kode pos (di banyak negara) dll. Adalah deretan angka desimal, tetapi tidak masuk akal untuk menambah, mengurangi atau mengalikannya, jadi itu bukan angka. Mereka kebetulan adalah string angka desimal, tetapi harus diperlakukan sebagai string karakter. (Kode pos di Kanada dan Inggris mengandung huruf dan angka.)
jcsahnwaldt mengatakan GoFundMonica
102

>>>adalah unsigned-shift; itu akan memasukkan 0. >>ditandatangani, dan akan memperpanjang bit tanda.

JLS 15.19 Operator Pergeseran

Operator shift meliputi shift kiri <<, shift kanan yang ditandatangani >>, dan shift kanan yang tidak ditandatangani>>> .

Nilai n>>sadalah nbenar-bergeser sposisi bit dengan tanda-ekstensi .

Nilai n>>>sadalah nbenar-bergeser sposisi bit dengan nol-ekstensi .

    System.out.println(Integer.toBinaryString(-1));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >> 16));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >>> 16));
    // prints "1111111111111111"

Untuk membuatnya lebih jelas, tambahkan rekan positif

System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"

Karena positif, baik shift yang ditandatangani maupun yang tidak ditandatangani akan menambah 0 ke paling kiri sedikit.

Pertanyaan-pertanyaan Terkait

polygenelubricants
sumber
Tanpa contoh Anda, saya tidak akan mendapatkannya.
mr5
47

Mereka berdua bergeser ke kanan, tetapi >>>benarunsigned

Dari dokumentasi :

Operator pergeseran kanan yang tidak ditandatangani ">>>" menggeser nol ke posisi paling kiri, sedangkan posisi paling kiri setelah ">>" tergantung pada ekstensi tanda.

Mat
sumber
12
dapatkah Anda jelaskan dengan sebuah contoh
Kasun Siyambalapitiya
1
Saya juga berpikir Anda harus memberi contoh.
byxor
Saya kira itu >>>tidak ditandatangani, tetapi mengapa 7>>32=7? Saya berlari satu putaran yang melakukan satu per satu dan melihat bahwa setelah 32pergantian, kembali ke 7. Satu-satunya cara agar hal ini masuk akal adalah bahwa untuk setiap angka yang digeser, ia memasuki "lingkaran luar". Setelah 32bergeser, entah bagaimana kembali ke posisi itu, tapi jelas itu masih tidak masuk akal. Apa yang sedang terjadi?
Ian Limarta
@IanLimarta Tidak? Saya baru mendapatkan 0. ( for (int i = 7 << 1, j = 0; j < 32; j++) System.out.println(Integer.toString(i >>= 1, 2));) Jika Anda maksud mengapa >>32itu sendiri mengembalikan nilai asli, lihat ini .
Moira
Maafkan saya. Maksud saya mengapa '7 >>> 32 = 7'.
Ian Limarta
40

Pergeseran kanan logis ( v >>> n) mengembalikan nilai di mana bit vtelah bergeser ke kanan oleh nposisi bit, dan 0 bergeser dari sisi kiri. Pertimbangkan untuk mengubah nilai 8-bit, ditulis dalam biner:

01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000

Jika kita menafsirkan bit sebagai bilangan bulat non-negatif yang tidak ditandatangani, pergeseran kanan logis memiliki efek membagi angka dengan kekuatan yang sesuai dari 2. Namun, jika angka tersebut dalam representasi dua komplemen, pergeseran kanan logis tidak dengan benar membagi angka negatif . Sebagai contoh, pergeseran kanan kedua di atas bergeser 128 ke 32 ketika bit ditafsirkan sebagai angka yang tidak ditandai. Tapi itu bergeser -128 ke 32 ketika, seperti khas di Jawa, bit ditafsirkan dalam komplemen dua.

Oleh karena itu, jika Anda bergeser untuk membagi dengan kekuatan dua, Anda ingin aritmatika bergeser ke kanan ( v >> n). Ini mengembalikan nilai di mana bit vtelah bergeser ke kanan oleh nposisi bit, dan salinan bit paling kiri dari v digeser dari sisi kiri:

01111111 >> 2 = 00011111
10000000 >> 2 = 11100000

Ketika bit adalah angka dalam representasi dua-pelengkap, pergeseran kanan aritmatika memiliki efek membagi dengan kekuatan dua. Ini berfungsi karena bit paling kiri adalah bit tanda. Membagi dengan kekuatan dua harus menjaga tanda itu tetap sama.

andru
sumber
38

>>>akan selalu menempatkan 0 di bit paling kiri, sementara >>akan menempatkan 1 atau 0 tergantung pada apa tanda itu.

corsiKa
sumber
10

Baca lebih lanjut tentang Operator Bitwise dan Bit Shift

>>      Signed right shift
>>>     Unsigned right shift

Pola bit diberikan oleh operan kiri, dan jumlah posisi untuk bergeser oleh operan kanan. Operator shift kanan yang tidak ditandatangani >>> menggeser nol ke posisi paling kiri ,

sedangkan posisi paling kiri setelah >>tergantung pada ekstensi tanda.

Dengan kata sederhana >>>selalu menggeser nol ke posisi paling kiri sedangkan >>bergeser berdasarkan tanda angka yaitu 1 untuk angka negatif dan 0 untuk angka positif.


Misalnya coba dengan angka negatif maupun positif.

int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));

System.out.println();

c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));

keluaran:

11111111111111111111111111011001
11111111111111111111111101100100
  111111111111111111111111011001
11111111111111111111111101100100

                          100110
                        10011000
                          100110
                        10011000
Braj
sumber
Terima kasih. Hanya ingin menambahkan komentar untuk referensi representasi bit untuk Integer.MAX_VALUE, Integer.MIN_VALUE, -1, 0, 1 . misalnya System.out.println(Integer.MAX_VALUE + ": " + String.format("%32s", Integer.toBinaryString(Integer.MAX_VALUE)).replace(' ', '0')):; Integer.MAX_VALUE : 01111111111111111111111111111111; Integer.MIN_VALUE : 10000000000000000000000000000000; -1 : 11111111111111111111111111111111; 0 : 00000000000000000000000000000000; 1 : 00000000000000000000000000000001
Andy Dong
6

Operator logis shift kanan ( >>> N) menggeser bit ke kanan dengan posisi N, membuang bit tanda dan mengisi bit paling kiri N dengan 0. Sebagai contoh:

-1 (in 32-bit): 11111111111111111111111111111111

setelah >>> 1operasi menjadi:

2147483647: 01111111111111111111111111111111

Operator aritmatika shift kanan ( >> N) juga menggeser bit ke kanan dengan posisi N, tetapi mempertahankan bit tanda dan membalut bit paling kiri N dengan bit 1. Sebagai contoh:

-2 (in 32-bit): 11111111111111111111111111111110

setelah >> 1operasi menjadi:

-1: 11111111111111111111111111111111
bigT
sumber