Jawaban:
>>
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
.
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?
String
juga dapat dianggap sebagai a char[]
. Dia tidak mengatakan bahwa a char
bukan angka; dia hanya mengatakan bahwa itu nomor yang tidak ditandatangani . Saya pikir di situlah dia tersesat.
>>>
adalah unsigned-shift; itu akan memasukkan 0. >>
ditandatangani, dan akan memperpanjang bit tanda.
Operator shift meliputi shift kiri
<<
, shift kanan yang ditandatangani>>
, dan shift kanan yang tidak ditandatangani>>>
.Nilai
n>>s
adalahn
benar-bergesers
posisi bit dengan tanda-ekstensi .Nilai
n>>>s
adalahn
benar-bergesers
posisi 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.
1 >>> 32 == 1
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.
>>>
tidak ditandatangani, tetapi mengapa 7>>32=7
? Saya berlari satu putaran yang melakukan satu per satu dan melihat bahwa setelah 32
pergantian, kembali ke 7
. Satu-satunya cara agar hal ini masuk akal adalah bahwa untuk setiap angka yang digeser, ia memasuki "lingkaran luar". Setelah 32
bergeser, entah bagaimana kembali ke posisi itu, tapi jelas itu masih tidak masuk akal. Apa yang sedang terjadi?
Pergeseran kanan logis ( v >>> n
) mengembalikan nilai di mana bit v
telah bergeser ke kanan oleh n
posisi 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 v
telah bergeser ke kanan oleh n
posisi 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.
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
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
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 >>> 1
operasi 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 >> 1
operasi menjadi:
-1: 11111111111111111111111111111111