Operator bitwise dan shift (referensi C#)
Operator bitwise dan shift mencakup pelengkap bitwise tidak biasa, shift kiri dan kanan biner, shift kanan yang tidak ditandatangani, dan logis biner AND, OR, dan operator OR eksklusif. Operan ini mengambil operand dari jenis numerik integral atau jenis karakter.
- Operator unary
~
(pelengkap bitwise) - Operator biner
<<
(shift kiri),>>
(shift kanan), dan>>>
(shift kanan tidak ditandatangani) - Operator biner
&
(AND LOGIS),|
(OR LOGIS), dan^
(OR eksklusif logis)
Operator tersebut didefinisikan untuk jenis int
, uint
, long
, dan ulong
. Ketika kedua operand adalah dari jenis integral lainnya (sbyte
, byte
, short
ushort
, atau char
), nilainya dikonversi ke jenis int
, yang juga merupakan jenis hasil operasi. Ketika operan dari jenis integral yang berbeda, nilainya dikonversi ke terdekat yang berisi jenis integral. Untuk informasi selengkapnya, lihat bagian Promosi numerik dari spesifikasi bahasa C#. Operator majemuk (seperti >>=
) tidak mengonversi argumen mereka menjadi int
atau memiliki jenis hasil int
.
Operator &
, |
, dan ^
juga didefinisikan untuk operand jenis bool
. Untuk informasi selengkapnya, lihat Konversi jenis boolean.
Operasi bitwise dan shift tidak menyebabkan luapan dan menghasilkan hasil yang sama dalam konteks dicentang dan tidak dicentang.
Operator ~
menghasilkan pelengkap bitwise dari operannya dengan membalikkan setiap bit:
uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;
uint b = ~a;
Console.WriteLine(Convert.ToString(b, toBase: 2));
// Output:
// 11110000111100001111000011110011
Anda juga dapat menggunakan simbol ~
untuk mendeklarasikan penutup. Untuk informasi selengkapnya, lihat Penutup.
Operator <<
menggeser operand sebelah kirinya ke kiri dengan jumlah bit yang ditentukan oleh operand kanannya. Untuk informasi tentang pengoperasian sebelah kanan menentukan jumlah shift, lihat jumlah Shift dari bagian operator shift.
Operasi shift kiri membuang bit urutan tinggi yang berada di luar rentang jenis hasil, dan mengatur posisi bit kosong berurutan rendah ke nol, seperti ditunjukkan contoh berikut:
uint x = 0b_1100_1001_0000_0000_0000_0000_0001_0001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2)}");
uint y = x << 4;
Console.WriteLine($"After: {Convert.ToString(y, toBase: 2)}");
// Output:
// Before: 11001001000000000000000000010001
// After: 10010000000000000000000100010000
Karena operator shift didefinisikan hanya untuk jenis int
, uint
, long
, dan ulong
, hasil operasi selalu berisi minimal 32 bit. Jika operand sebelah kiri adalah jenis integral lain (sbyte
, byte
, short
, ushort
, atau char
), nilainya dikonversi ke jenis int
, seperti ditunjukkan contoh berikut:
byte a = 0b_1111_0001;
var b = a << 8;
Console.WriteLine(b.GetType());
Console.WriteLine($"Shifted byte: {Convert.ToString(b, toBase: 2)}");
// Output:
// System.Int32
// Shifted byte: 1111000100000000
Operator >>
menggeser operand sebelah kirinya ke kiri dengan jumlah bit yang ditentukan oleh operand kanannya. Untuk informasi tentang pengoperasian sebelah kanan menentukan jumlah shift, lihat jumlah Shift dari bagian operator shift.
Operasi shift kanan membuang bit berurutan rendah, seperti ditunjukkan contoh berikut:
uint x = 0b_1001;
Console.WriteLine($"Before: {Convert.ToString(x, toBase: 2), 4}");
uint y = x >> 2;
Console.WriteLine($"After: {Convert.ToString(y, toBase: 2).PadLeft(4, '0'), 4}");
// Output:
// Before: 1001
// After: 0010
Posisi bit kosong berurutan tinggi diatur berdasarkan jenis operand sebelah kiri sebagai berikut:
Jika operand sebelah kiri berjenis
int
ataulong
, operator shift kanan melakukan pergeseran aritmatika : nilai bit yang paling signifikan (bit tanda) dari operand sebelah kiri disebarkan ke posisi bit kosong urutan tinggi. Artinya, posisi bit kosong urutan tinggi diatur ke nol jika operand sebelah kiri tidak negatif dan diatur ke satu jika negatif.int a = int.MinValue; Console.WriteLine($"Before: {Convert.ToString(a, toBase: 2)}"); int b = a >> 3; Console.WriteLine($"After: {Convert.ToString(b, toBase: 2)}"); // Output: // Before: 10000000000000000000000000000000 // After: 11110000000000000000000000000000
Jika operand sebelah kiri berjenis
uint
atauulong
, operator shift kanan melakukan shift logis: posisi bit kosong urutan tinggi selalu diatur ke nol.uint c = 0b_1000_0000_0000_0000_0000_0000_0000_0000; Console.WriteLine($"Before: {Convert.ToString(c, toBase: 2), 32}"); uint d = c >> 3; Console.WriteLine($"After: {Convert.ToString(d, toBase: 2).PadLeft(32, '0'), 32}"); // Output: // Before: 10000000000000000000000000000000 // After: 00010000000000000000000000000000
Catatan
Gunakan operator shift kanan yang tidak ditandatangani untuk melakukan pergeseran logis pada operan jenis bilangan bulat yang ditandatangani. Ini lebih disukai untuk mentransmisikan operand sebelah kiri ke jenis yang tidak ditandatangani dan kemudian mentransmisikan hasil operasi shift kembali ke jenis yang ditandatangani.
Tersedia di C# 11 dan yang lebih baru, >>>
operator menggeser operand kirinya ke kanan dengan jumlah bit yang ditentukan oleh operand tangan kanannya. Untuk informasi tentang pengoperasian sebelah kanan menentukan jumlah shift, lihat jumlah Shift dari bagian operator shift.
Operator >>>
selalu melakukan pergeseran logis . Artinya, posisi bit kosong berurutan tinggi selalu diatur ke nol, terlepas dari jenis operand sebelah kiri. Operator >>
melakukan pergeseran aritmatika (yaitu, nilai bit yang paling signifikan disebarkan ke posisi bit kosong urutan tinggi) jika operand sebelah kiri adalah jenis yang ditandatangani. Contoh berikut menunjukkan perbedaan antara >>
operator dan >>>
untuk operand kiri negatif:
int x = -8;
Console.WriteLine($"Before: {x,11}, hex: {x,8:x}, binary: {Convert.ToString(x, toBase: 2), 32}");
int y = x >> 2;
Console.WriteLine($"After >>: {y,11}, hex: {y,8:x}, binary: {Convert.ToString(y, toBase: 2), 32}");
int z = x >>> 2;
Console.WriteLine($"After >>>: {z,11}, hex: {z,8:x}, binary: {Convert.ToString(z, toBase: 2).PadLeft(32, '0'), 32}");
// Output:
// Before: -8, hex: fffffff8, binary: 11111111111111111111111111111000
// After >>: -2, hex: fffffffe, binary: 11111111111111111111111111111110
// After >>>: 1073741822, hex: 3ffffffe, binary: 00111111111111111111111111111110
Operator &
menghitung logis bitwise DAN dari operan integralnya:
uint a = 0b_1111_1000;
uint b = 0b_1001_1101;
uint c = a & b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10011000
Untuk operand bool
, operator &
menghitung AND logis dari operand. Operator &
unary adalah alamat operator.
Operator ^
menghitung OR eksklusif logis bitwise, juga dikenal sebagai XOR logis bitwise, dari operand integralnya:
uint a = 0b_1111_1000;
uint b = 0b_0001_1100;
uint c = a ^ b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 11100100
Untuk operand bool
, operator ^
menghitung OR eksklusif logis dari operand.
Operator |
menghitung OR logis bitwise dari operand integralnya:
uint a = 0b_1010_0000;
uint b = 0b_1001_0001;
uint c = a | b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10110001
Untuk operand bool
, operator |
menghitung OR logis dari operand.
Untuk op
operator biner, ekspresi penetapan campuran dari formulir
x op= y
setara dengan:
x = x op y
kecuali x
hanya dievaluasi sekali.
Contoh berikut menunjukkan penggunaan penetapan campuran dengan operator bitwise dan shift:
uint INITIAL_VALUE = 0b_1111_1000;
uint a = INITIAL_VALUE;
a &= 0b_1001_1101;
Display(a); // output: 10011000
a = INITIAL_VALUE;
a |= 0b_0011_0001;
Display(a); // output: 11111001
a = INITIAL_VALUE;
a ^= 0b_1000_0000;
Display(a); // output: 01111000
a = INITIAL_VALUE;
a <<= 2;
Display(a); // output: 1111100000
a = INITIAL_VALUE;
a >>= 4;
Display(a); // output: 00001111
a = INITIAL_VALUE;
a >>>= 4;
Display(a); // output: 00001111
void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2).PadLeft(8, '0'), 8}");
Karena promosi numerik, hasil op
operasi mungkin tidak secara implisit dapat dikonversi ke jenis T
dari x
. Dalam kasus seperti itu, jika op
adalah operator yang telah ditentukan sebelumnya dan hasil operasi secara eksplisit dapat dikonversi ke jenis T
dari x
, ekspresi penetapan campuran formulir x op= y
setara dengan x = (T)(x op y)
, kecuali x
hanya dievaluasi sekali. Contoh berikut menunjukkan perilaku tersebut:
byte x = 0b_1111_0001;
int b = x << 8;
Console.WriteLine($"{Convert.ToString(b, toBase: 2)}"); // output: 1111000100000000
x <<= 8;
Console.WriteLine(x); // output: 0
Daftar berikut mengurutkan operator bitwise dan shift mulai dari prioritas tertinggi ke terendah:
- Operator pelengkap bitwise
~
- Operator
<<
shift ,>>
, dan>>>
- Operator AND logis
&
- Operator OR eksklusif logis
^
- Operator OR logis
|
Gunakan tanda kurung ()
, untuk mengubah urutan evaluasi yang diberlakukan oleh prioritas operator:
uint a = 0b_1101;
uint b = 0b_1001;
uint c = 0b_1010;
uint d1 = a | b & c;
Display(d1); // output: 1101
uint d2 = (a | b) & c;
Display(d2); // output: 1000
void Display(uint x) => Console.WriteLine($"{Convert.ToString(x, toBase: 2), 4}");
Untuk daftar lengkap operator C# yang diurutkan berdasarkan tingkat prioritas, lihat bagian Prioritas operator dari artikel operator C#.
x << count
Untuk ekspresi , x >> count
, dan x >>> count
, jumlah shift aktual tergantung pada jenis x
sebagai berikut:
Jika jenis
x
adalahint
atauuint
, jumlah shift ditentukan oleh lima bit urutan rendah dari operand kanan. Artinya, jumlah shift dihitung daricount & 0x1F
(ataucount & 0b_1_1111
).Jika jenis
x
adalahlong
atauulong
, jumlah shift ditentukan oleh lima bit urutan rendah dari operand kanan. Artinya, jumlah shift dihitung daricount & 0x3F
(ataucount & 0b_11_1111
).
Contoh berikut menunjukkan perilaku tersebut:
int count1 = 0b_0000_0001;
int count2 = 0b_1110_0001;
int a = 0b_0001;
Console.WriteLine($"{a} << {count1} is {a << count1}; {a} << {count2} is {a << count2}");
// Output:
// 1 << 1 is 2; 1 << 225 is 2
int b = 0b_0100;
Console.WriteLine($"{b} >> {count1} is {b >> count1}; {b} >> {count2} is {b >> count2}");
// Output:
// 4 >> 1 is 2; 4 >> 225 is 2
int count = -31;
int c = 0b_0001;
Console.WriteLine($"{c} << {count} is {c << count}");
// Output:
// 1 << -31 is 2
Catatan
Seperti yang ditunjukkan oleh contoh sebelumnya, hasil dari operasi shift bisa tidak nol bahkan jika nilai operand kanan lebih besar dari jumlah bit di operand kiri.
Operator ~
, &
, |
, dan ^
juga didukung oleh jenis enumerasi apa pun. Untuk operand dengan jenis enumerasi yang sama, operasi logis dilakukan pada nilai yang sesuai dari jenis integral yang mendasar. Misalnya, untuk salah satu x
dan y
dari jenis enumerasi T
dengan jenis U
yang mendasar, ekspresi x & y
menghasilkan hasil yang sama dengan ekspresi (T)((U)x & (U)y)
.
Anda biasanya menggunakan operator logis bitwise dengan jenis enumerasi yang ditentukan dengan atribut Bendera. Untuk informasi selengkapnya, lihat bagian Jenis enumerasi sebagai bendera bit dari artikel Jenis enumerasi.
Jenis yang ditentukan pengguna dapat membebani ~
operator , , <<
>>
, >>>
, &
, |
dan ^
. JIka operator biner kelebihan beban, operator penetapan campuran yang sesuai juga secara implisit kelebihan beban. Jenis yang ditentukan pengguna tidak dapat secara eksplisit membebani operator penetapan majemuk.
Jika jenis T
yang ditentukan pengguna membebani <<
operator , , >>
atau >>>
, jenis operand sebelah kiri harus T
. Dalam C# 10 dan yang lebih lama, jenis operand tangan kanan harus int
; dimulai dengan C# 11, jenis operan tangan kanan operator shift yang kelebihan beban dapat berupa apa pun.
Untuk informasi selengkapnya, lihat bagian berikut dari spesifikasi bahasa C#:
Umpan balik .NET
.NET adalah proyek sumber terbuka. Pilih tautan untuk memberikan umpan balik: