Advertisement
Scroll to top
Read Time: 15 min

() translation by (you can also view the original English article)

Operator Bitwise adalah operator yang tampak aneh yang mungkin terlihat sulit dimengerti ... tetapi tidak lagi! Artikel yang mudah diikuti ini akan membantu Anda memahami apa yang mereka dan bagaimana menggunakannya, dengan beberapa contoh praktis juga untuk menunjukkan kepada Anda kapan dan mengapa Anda membutuhkannya.


Pengantar

Operator Bitwise adalah operator (seperti, *, **, dll.) Yang beroperasi pada ints dan uints pada level biner. Ini berarti mereka melihat langsung pada digit biner atau bit dari suatu integer. Ini semua terdengar menakutkan, tetapi sebenarnya operator bitwise cukup mudah digunakan dan juga sangat berguna!

Namun, penting bagi Anda untuk memahami angka biner dan angka heksadesimal. Jika tidak, silakan lihat artikel ini - ini akan sangat membantu Anda! Di bawah ini adalah aplikasi kecil yang memungkinkan Anda mencoba operator bitwise yang berbeda.

Jangan khawatir jika Anda tidak mengerti apa yang sedang terjadi, semuanya akan segera jelas ...


Mengenali Operator Bitwise

Mari kita lihat operator bitwise yang memasok AS3. Banyak bahasa lain yang cukup mirip (misalnya, JavaScript dan Java memiliki operator yang identik):

  • & (bitwise AND)
  • | (bitwise OR)
  • ~ (bitwise NOT)
  • ^ (bitwise XOR)
  • << (bitwise pergeseran kiri)
  • >> (bitwise pergeseran kanan)
  • >>> (pergeseran kanan bergeser bitwise)
  • &= (bitwise AND assignment)
  • |= (bitwise OR assignment)
  • ^= (bitwise XOR assignment)
  • <<= (bitwise pergeseran kiri dan samadengan)
  • >>= (bitwise pergeseran kanan dan samadengan)
  • >>>= (bitwise unsigned right shift and assignment)

Ada beberapa hal yang harus Anda ambil dari ini: Pertama, beberapa operator bitwise terlihat mirip dengan operator yang pernah Anda gunakan sebelumnya (* vs. **, | vs. ||). Ini karena mereka agak mirip.

Kedua, sebagian besar operator bitwise datang dengan formulir penugasan gabungan dari mereka sendiri. Ini sama dengan bagaimana Anda dapat menggunakan dan =, - dan - =, dll.


Operator &

Atas pertama: operator DAN bitwise, *. Head-up yang cepat meskipun: biasanya, ints dan uints mengambil 4 byte atau 32 bit ruang. Ini berarti setiap int atau uint disimpan sebagai 32 digit biner. Demi tutorial ini, kita akan berpura-pura kadang-kadang bahwa ints dan uints hanya mengambil 1 byte dan hanya memiliki 8 digit biner.

Operator * membandingkan setiap digit biner dua bilangan bulat dan mengembalikan bilangan bulat baru, dengan 1 di mana kedua bilangan memiliki 1 dan 0 di tempat lain. Diagram bernilai seribu kata, jadi inilah satu untuk menjelaskan semuanya. Ini mewakili melakukan 37 * 23, yang sama dengan 5.

Bitwise And operator example

Perhatikan bagaimana setiap digit biner 37 dan 23 dibandingkan, dan hasilnya memiliki 1 di mana keduanya 37 dan 23 memiliki 1, dan hasilnya memiliki 0 sebaliknya.

Cara berpikir umum tentang digit biner adalah true atau false. Artinya, 1 sama dengan true dan 0 sama dengan false. Ini membuat operator & lebih masuk akal.

Ketika kita membandingkan dua boolean, kita biasanya melakukan boolean1 && boolean2. Ekspresi itu hanya benar jika boolean1 dan boolean2 benar. Dengan cara yang sama, integer1 & integer2 adalah ekuivalen, karena operator & hanya menghasilkan 1 ketika kedua digit biner dari dua bilangan bulat kami adalah 1.

Berikut adalah tabel yang mewakili gagasan itu:

Bitwise AND table

Penggunaan operator * yang rapi adalah untuk memeriksa apakah suatu angka genap atau ganjil. Untuk bilangan bulat kita dapat memeriksa bit paling kanan (juga disebut bit paling signifikan) untuk menentukan apakah bilangan bulat itu ganjil atau genap. Ini karena ketika mengkonversi ke basis 10, bit paling kanan mewakili 20 atau 1. Ketika bit paling kanan adalah 1, kita tahu bahwa angka kita aneh karena kita menambahkan 1 ke sekelompok kekuatan dua yang akan selalu genap. Ketika bit paling kanan adalah 0, kita tahu nomor kita akan genap, karena ini hanya terdiri dari menambahkan banyak bilangan genap.

Inilah contohnya:

1
2
var randInt:int = int(Math.random()*1000);
3
if(randInt & 1)
4
{
5
  trace("Odd number.");
6
}
7
else
8
{
9
	trace("Even number.");
10
}

Di komputer saya, metode ini sekitar 66% lebih cepat daripada menggunakan randInt %  2 untuk memeriksa angka genap dan ganjil. Itu peningkatan kinerja yang bagus!


Operator |

Berikutnya adalah operator OR bitwise, |. Seperti yang Anda tebak, the | operator adalah ke || operator sebagai operator & adalah operator &&. The | operator membandingkan setiap digit biner di dua bilangan bulat dan mengembalikan 1 jika salah satunya adalah 1. Sekali lagi, ini mirip dengan || operator dengan boolean.

Bitwise OR table

Mari kita lihat contoh yang sama seperti sebelumnya, kecuali sekarang menggunakan | operator, bukan operator *. Kami sekarang melakukan 37 | 23 yang sama dengan 55:

Bitwise OR tableBitwise OR tableBitwise OR table

Bendera: Penggunaan Operator  & dan |

Kita bisa memanfaatkan * dan | operator untuk memungkinkan kami memberikan beberapa opsi ke fungsi dalam satu int.

Mari kita lihat situasi yang mungkin terjadi. Kami sedang membangun kelas jendela pop-up. Di bagian bawahnya, kita dapat memiliki tombol Ya, Tidak, Oke, atau Batal atau kombinasi apa pun dari mereka - bagaimana seharusnya kita melakukan ini? Inilah cara yang sulit:

1
2
public class PopupWindow extends Sprite
3
{
4
	// Variables, Constructor, etc...

5
6
7
	public static void showPopup(yesButton:Boolean, noButton:Boolean, okayButton:Boolean, cancelButton:Boolean)
8
	{
9
		if(yesButton)
10
		{
11
			// add YES button

12
		}
13
		
14
		if(noButton)
15
		{
16
			// add NO Button

17
		}
18
		// and so on for the rest of the buttons

19
	}
20
}

Apakah ini mengerikan? Tidak. Tapi itu buruk, jika Anda seorang programmer, harus mencari urutan argumen setiap kali Anda memanggil fungsi. Ini juga menjengkelkan - misalnya, jika Anda hanya ingin menampilkan tombol Batal, Anda harus mengatur semua Boolean lain ke false.

Mari kita gunakan apa yang kita pelajari tentang & dan | untuk membuat solusi yang lebih baik:

1
2
public class PopupWindow extends Sprite
3
{
4
	public static const YES:int = 1;
5
	public static const NO:int = 2;
6
	public static const OKAY:int = 4;
7
	public static const CANCEL:int = 8;
8
9
	public static void showPopup(buttons:int)
10
	{
11
		if(buttons & YES)
12
		{
13
			// add YES button

14
		}
15
		
16
		if(buttons & NO)
17
		{
18
			// add NO button

19
		}	
20
	}
21
}

Bagaimana programmer memanggil fungsi sehingga tombol Ya, tombol Tidak, dan tombol Batal muncul? Seperti ini:

1
2
PopupWindow.show(PopupWindow.YES | PopupWindow.NO | PopupWindow.CANCEL);

Apa yang sedang terjadi? Penting untuk dicatat bahwa konstanta kita dalam contoh kedua adalah semua kekuatan dua. Jadi, jika kita melihat bentuk binernya, kita akan melihat mereka semua memiliki satu digit sama dengan 1, dan sisanya sama dengan 0. Bahkan, mereka masing-masing memiliki digit yang berbeda sama dengan 1. Ini berarti bahwa tidak peduli bagaimana kita menggabungkannya dengan |, setiap kombinasi akan memberi kita nomor yang unik. Melihatnya dengan cara yang berbeda, hasil dari | kami pernyataan akan menjadi bilangan biner dengan 1 dimanapun pilihan kita memiliki 1.

Untuk contoh saat ini kami memiliki PopupWindow.YES | PopupWindow.NO | PopupWindow.CANCEL yang setara dengan 1 | 2 | 8 yang ditulis ulang dalam biner adalah 00000001 | 00000010 | 00001000 yang memberi kita hasil dari 00001011.

Sekarang, dalam fungsi showPopup() kami, kami menggunakan & untuk memeriksa opsi mana yang dilewati. Sebagai contoh, ketika kami memeriksa tombol & YES, semua bit dalam YES sama dengan 0 kecuali yang paling kanan. Jadi, kami pada dasarnya memeriksa apakah bit paling kanan di tombol adalah 1 atau tidak. Jika ya, tombol & YA tidak akan sama dengan 0 dan apapun dalam pernyataan if akan dieksekusi. Sebaliknya, jika bit paling kanan dalam tombol adalah 0, tombol & YA akan sama dengan 0, dan pernyataan if tidak akan dieksekusi.


Operator ~

Operator NOT bitwise sedikit berbeda dari dua yang telah kita lihat sejauh ini. Alih-alih mengambil bilangan bulat di setiap sisi itu, dibutuhkan integer hanya setelah itu. Ini seperti itu! operator, dan, tidak mengherankan, ia melakukan hal yang sama. Bahkan, sama seperti! membalik boolean dari true ke false atau sebaliknya, operator ~ membalik setiap digit biner dalam sebuah integer: dari 0 hingga 1 dan 1 hingga 0:

Bitwise OR table

Contoh cepat. Katakanlah kita memiliki bilangan bulat 37, atau 00100101. ~ 37 kemudian 11011010. Berapa nilai dasar 10 dari ini? Baik...


Dua Komplemen, uint vs. int, dan Lainnya!

Sekarang kesenangannya dimulai! Kita akan melihat lebih dekat angka-angka biner di komputer. Mari kita mulai dengan uint. Seperti disebutkan sebelumnya, sebuah uint biasanya berukuran 4 byte atau 32 bit, yang berarti ia memiliki 32 digit biner. Ini mudah dimengerti: untuk mendapatkan nilai dasar 10 kita cukup mengubah angka ke basis 10 secara teratur. Kami akan selalu mendapatkan angka positif.

Tapi bagaimana dengan int? Ini juga menggunakan 32 bit, tapi bagaimana cara menyimpan angka negatif? Jika Anda menebak bahwa digit pertama digunakan untuk menyimpan tanda, Anda berada di jalur yang benar. Mari kita lihat sistem komplemen kedua untuk menyimpan bilangan biner. Meskipun kami tidak akan membahas semua detail di sini, sistem pelengkap dua digunakan karena membuat aritmatika biner menjadi mudah.

Untuk menemukan komplemen kedua dari bilangan biner, kita cukup membalik semua bit (yaitu melakukan apa yang dilakukan oleh operator ~) dan menambahkan satu ke hasilnya. Mari coba ini dulu:

Two's Complement of 37

Kami kemudian mendefinisikan hasil kami sebagai nilai -37. Mengapa proses rumit ini dan tidak hanya membalik sedikit pertama dan memanggilnya -37?

Nah, mari kita ungkapan sederhana 37 + -37. Kita semua tahu ini harus sama dengan 0, dan ketika kita menambahkan 37 ke komplemen keduanya, itulah yang kita dapatkan:

37 + -37 in binary

Perhatikan bahwa karena bilangan bulat kami hanya memiliki delapan digit biner, 1 dalam hasil kami dijatuhkan, dan kami berakhir dengan 0, sebagaimana seharusnya.

Ringkasnya, untuk menemukan angka negatif, kita cukup mengambil komplemen keduanya. Kita bisa melakukan ini dengan membalik semua bit dan menambahkan satu.

Ingin mencoba ini sendiri? Tambahkan trace(~ 37 + 1); ke file AS3, lalu kompilasi dan jalankan. Anda akan melihat -37 dicetak, sebagaimana seharusnya.

Ada juga sedikit jalan pintas untuk melakukan hal ini dengan tangan: mulai dari kanan, bekerja ke kiri sampai Anda mencapai 1. Flip semua bit ke kiri 1 pertama ini.

Two's Complement of 37 Shortcut

Ketika kita melihat angka biner yang ditandatangani (dengan kata lain, salah satu yang bisa negatif, int bukan uint), kita dapat melihat pada digit paling kiri untuk mengatakan apakah itu negatif atau positif. Jika angka 0, maka angka tersebut positif dan kita dapat mengonversi ke basis 10 hanya dengan menghitung nilai basis 10-nya. Jika bit paling kiri adalah 1, maka angka tersebut negatif, jadi kita mengambil komplemen kedua dari angka tersebut untuk mendapatkan nilai positifnya dan kemudian cukup tambahkan tanda negatif.

Sebagai contoh, jika kita memiliki 11110010, kita tahu itu adalah angka negatif. Kita dapat menemukan komplemen dua dengan membalik semua digit di sebelah kiri paling kanan 1, memberi kita 00001110. Ini sama dengan 13, jadi kita tahu 11110010 sama dengan -13.


Operator ^

Kami kembali ke operator bitwise, dan selanjutnya adalah operator XOR bitwise. Tidak ada operator boolean yang setara dengan yang satu ini.

Operator ^ mirip dengan & dan | operator yang membutuhkan int atau uint di kedua sisi. Ketika menghitung jumlah yang dihasilkan, itu lagi membandingkan digit biner dari angka-angka ini. Jika satu atau yang lain adalah 1, itu akan memasukkan 1 dalam hasil, jika tidak maka akan memasukkan 0. Ini adalah tempat nama XOR, atau "eksklusif atau" berasal.

Bitwise XOR table

Mari kita lihat contoh umum kami:

Bitwise XOR exampleBitwise XOR exampleBitwise XOR example

Operator ^ memang memiliki kegunaan - sangat baik untuk mengubah digit biner - tetapi kami tidak akan membahas aplikasi praktis apa pun dalam artikel ini.


Operator <<

Kami sekarang berada di operator bithift, khususnya operator shift kiri bitwise di sini.

Ini bekerja sedikit berbeda dari sebelumnya. Alih-alih membandingkan dua bilangan bulat seperti &, |, dan ^ lakukan, operator ini menggeser bilangan bulat. Di sisi kiri operator adalah bilangan bulat yang sedang digeser, dan di sebelah kanan adalah berapa banyak yang akan digeser. Jadi, misalnya, 37 << 3 memindahkan nomor 37 ke kiri oleh 3 tempat. Tentu saja, kami bekerja dengan representasi biner 37.

Mari kita lihat contoh ini (ingat, kita hanya akan berpura-pura bilangan bulat hanya memiliki 8 bit, bukan 32). Di sini kita memiliki nomor 37 yang duduk di blok memori 8 bit yang bagus.

Bitwise Left Shift exampleBitwise Left Shift exampleBitwise Left Shift example

Baiklah, mari kita geser semua digit ke kiri oleh 3, seperti 37 << 3 akan lakukan:

Bitwise Left Shift exampleBitwise Left Shift exampleBitwise Left Shift example

Tapi sekarang kita memiliki masalah kecil - apa yang kita lakukan dengan 3 bit memori terbuka di mana kita memindahkan angka dari?

Bitwise Left Shift exampleBitwise Left Shift exampleBitwise Left Shift example

Tentu saja! Setiap titik kosong hanya diganti dengan angka 0. Kami berakhir dengan 00101000. Dan itu semua ada di bagian kiri. Perlu diingat bahwa Flash selalu menganggap hasil dari bitshift kiri adalah int, bukan uint. Jadi jika Anda memerlukan sebuah uint untuk beberapa alasan, Anda harus melemparkannya ke sebuah uint seperti ini: uint(37 << 3). Pengecoran ini tidak benar-benar mengubah informasi biner apa pun, hanya bagaimana Flash menafsirkannya (semua hal yang melengkapi keduanya).

Fitur menarik dari bitshift kiri adalah sama dengan mengalikan angka dua dengan kekuatan shiftAmount-th. Jadi, 37 << 3 == 37 * Math.pow (2,3) == 37 * 8. Jika Anda dapat menggunakan shift kiri daripada Math.pow, Anda akan melihat peningkatan kinerja yang sangat besar.

Anda mungkin telah memperhatikan bahwa angka biner yang kami gunakan tidak sama dengan 37 * 8. Ini hanya dari penggunaan kami hanya 8 bit memori untuk bilangan bulat; jika Anda mencobanya dalam ActionScript, Anda akan mendapatkan hasil yang benar. Atau, coba dengan demo di bagian atas halaman!


Operator >>

Sekarang kita memahami bithift kiri, yang berikutnya, pemotongan bit yang tepat, akan mudah. Semua slide ke kanan jumlah yang kami tentukan. Satu-satunya perbedaan kecil adalah apa yang diisi dengan bit kosong.

Jika kita mulai dengan angka negatif (angka biner di mana bit paling kiri adalah 1), semua ruang kosong diisi dengan 1. Jika kita mulai dengan angka positif (di mana bit paling kiri, atau paling signifikan bit, adalah 0), maka semua ruang kosong diisi dengan 0. Sekali lagi, ini semua kembali ke komplemen dua.

Meskipun ini terdengar rumit, pada dasarnya hanya mempertahankan tanda nomor yang kita mulai dengan. Jadi -8 >> 2 == -2 sementara 8 >> 2 == 2. Saya akan merekomendasikan mencoba mereka di atas kertas sendiri.

Karena >> adalah kebalikan dari <<, tidak mengherankan bahwa menggeser angka ke kanan sama dengan membaginya dengan 2 ke kekuatan shiftAmount. Anda mungkin telah memperhatikan ini dari contoh di atas. Sekali lagi, jika Anda dapat menggunakan ini untuk menghindari memanggil Math.pow, Anda akan mendapatkan peningkatan kinerja yang signifikan.


Operator >>>

Operator bitwise terakhir kami adalah pergeseran kanan bitwise unsigned. Ini sangat mirip dengan shift kanan bitwise biasa, kecuali bahwa semua bit kosong di sebelah kiri diisi dengan 0s. Ini berarti hasil dari operator ini selalu bilangan bulat positif dan selalu memperlakukan bilangan bulat yang bergeser sebagai bilangan bulat unsigned. Kami tidak akan menjalankan contoh ini di bagian ini, tetapi kami akan segera menggunakannya.


Menggunakan Operator Bitwise untuk Bekerja Dengan Warna

Salah satu penggunaan yang paling praktis dari operator bitwise di Actionscript 3 bekerja dengan warna, yang biasanya disimpan sebagai uints.

Format standar untuk warna adalah menulisnya dalam heksadesimal: 0xAARRGGBB - setiap huruf mewakili digit heksadesimal. Di sini, dua digit heksadesimal pertama, yang setara dengan delapan digit biner pertama, mewakili alpha kami, atau transparansi. Delapan bit berikutnya mewakili jumlah warna merah dalam warna kami (jadi bilangan bulat dari 0 hingga 255), delapan berikutnya jumlah hijau, dan delapan terakhir mewakili jumlah biru dalam warna kami.

Tanpa operator bitwise, sangat sulit untuk bekerja dengan warna dalam format ini - tetapi dengan mereka itu mudah!

Tantangan 1: Temukan jumlah biru dalam warna: Menggunakan operator &, cobalah untuk menemukan jumlah warna biru dalam warna acak.

1
2
public function findBlueComponent(color:uint):uint
3
{
4
	// Your code here!

5
}

Kami membutuhkan cara untuk 'menghapus' atau menyembunyikan semua data lain dalam color dan hanya memiliki komponen biru yang tersisa. Ini mudah, sebenarnya! Jika kami mengambil color & 0x000000FF - atau, ditulis lebih sederhana, color & 0xFF - kami hanya akan mendapatkan komponen biru.

Bitwise Left Shift exampleBitwise Left Shift exampleBitwise Left Shift example

Seperti yang Anda lihat dari atas dan Anda pelajari dalam deskripsi operator &, setiap digit biner & 0 akan selalu sama dengan 0, sementara digit biner & 1 apa pun akan mempertahankan nilainya. Jadi jika kita menutupi warna kita dengan 0xFF yang hanya memiliki 1s di mana komponen biru warna kita berada, kita berakhir hanya dengan komponen biru.

Tantangan 2: Temukan jumlah warna merah: Menggunakan dua operator bitwise, coba temukan jumlah merah dalam warna acak.

1
2
public function findRedComponent(color:uint):uint
3
{
4
	// Your code here!

5
}

Kami sebenarnya memiliki dua solusi untuk masalah ini. Satu menjadi return (color & 0xFF0000) >> 16; dan yang lainnya menjadi return (color >> 16) & 0xFF;

Ini sangat mirip dengan Challenge 1, kecuali bahwa kita harus menggeser jawaban kita di beberapa titik.

Tantangan 3: Temukan transparansi warna: Hanya menggunakan satu operator bitwise, cobalah untuk menemukan alfa warna (integer dari 0 hingga 255).

1
2
public function findAlphaComponent(color:uint):uint
3
{
4
	// Your code here!

5
}

Yang ini adalah sentuhan yang lebih rumit. Kita harus berhati-hati dengan operater shift yang mana yang kita pilih. Karena kami bekerja dengan digit paling kiri dari sebuah uint, kami ingin menggunakan operator >>>. Jadi, jawaban kami hanyalah return color >>> 24;.

Tantangan Akhir: Buat warna dari komponennya: Menggunakan << dan | operator, ambil komponen-komponen suatu warna dan gabungkan mereka menjadi satu bagian uint.

1
2
public function createColor(a:uint, r:uint, g:uint, b:uint):uint
3
{
4
	// Your code here!

5
}

Di sini, kita harus menggeser setiap komponen ke posisi yang benar, lalu menggabungkannya. Kami ingin Flash memperlakukannya sebagai integer unsigned, jadi kami mentransmisikannya ke sebuah uint: return uint ((a << 24) | (r << 16) | (g << 8) | b);


Operator Senyawa

Anda mungkin telah memperhatikan saya telah lalai menjelaskan operator bitwise gabungan. Bayangkan kita memiliki bilangan bulat x. Kemudian, x = x & 0xFF sama dengan x & = 0xFF, x = x | 256 adalah sama dengan x | = 256, dan seterusnya untuk sisa operator majemuk.


Kesimpulan

Terima kasih telah membaca artikel ini! Saya harap Anda sekarang memahami operator bitwise dan dapat menggunakannya dalam kode AS3 Anda (atau dalam banyak bahasa lain!). Seperti biasa, jika Anda memiliki pertanyaan atau komentar, silakan tinggalkan di bawah.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.