Apa itu operator bitwise?


129

Saya seseorang yang menulis kode hanya untuk bersenang-senang dan belum benar-benar menyelidiki itu baik dalam pengaturan akademik atau profesional, jadi hal-hal seperti operator bitwise ini benar-benar lolos dari saya.

Saya sedang membaca artikel tentang JavaScript, yang tampaknya mendukung operasi bitwise. Saya terus melihat operasi ini disebutkan di beberapa tempat, dan saya sudah mencoba membaca tentang mencari tahu apa itu sebenarnya, tapi sepertinya saya tidak mengerti sama sekali. Jadi apa mereka Contoh yang jelas akan bagus! : D

Hanya beberapa pertanyaan lagi - apa saja aplikasi praktis dari operasi bitwise? Kapan Anda menggunakannya?


2
Untuk pertanyaan lebih lanjut, Anda mungkin ingin menambahkan pertanyaan SO baru dan referensi yang satu ini. Anda mungkin akan mendapatkan serangkaian jawaban yang lebih baik dengan cara itu.
Greg Hewgill

Jawaban:


186

Karena tidak ada yang menyinggung masalah mengapa ini berguna:

Saya sering menggunakan operasi bitwise saat bekerja dengan flag. Misalnya, jika Anda ingin meneruskan serangkaian flag ke operasi (misalnya File.Open(),, dengan mode Baca dan mode Tulis keduanya diaktifkan), Anda bisa meneruskannya sebagai nilai tunggal. Ini dilakukan dengan menetapkan setiap flag yang mungkin, bit itu sendiri dalam bitset (byte, pendek, int, atau panjang). Sebagai contoh:

 Read: 00000001
Write: 00000010

Jadi jika Anda ingin lulus baca DAN menulis, Anda akan lulus (BACA | MENULIS) yang kemudian menggabungkan keduanya menjadi

00000011

Yang kemudian dapat didekripsi di ujung yang lain seperti:

if ((flag & Read) != 0) { //...

yang memeriksa

00000011 &
00000001

yang kembali

00000001

yang bukan 0, sehingga flag tidak menentukan BACA.

Anda dapat menggunakan XOR untuk mengaktifkan berbagai bit. Saya telah menggunakan ini ketika menggunakan flag untuk menentukan input directional (Atas, Bawah, Kiri, Kanan). Sebagai contoh, jika sebuah sprite bergerak secara horizontal, dan saya ingin itu berbalik:

     Up: 00000001
   Down: 00000010
   Left: 00000100
  Right: 00001000
Current: 00000100

Saya cukup XOR nilai saat ini dengan (KIRI | KANAN) yang akan mematikan KIRI dan KANAN, dalam hal ini.

Bit Shifting berguna dalam beberapa kasus.

x << y

sama dengan

x * 2 y

jika Anda perlu dengan cepat mengalikan dengan kekuatan dua, tapi hati-hati untuk menggeser 1-bit ke bit atas - ini membuat angka negatif kecuali itu tidak ditandatangani. Ini juga berguna ketika berhadapan dengan berbagai ukuran data. Misalnya, membaca bilangan bulat dari empat byte:

int val = (A << 24) | (B << 16) | (C << 8) | D;

Dengan asumsi bahwa A adalah byte yang paling signifikan dan D yang paling sedikit. Itu akan berakhir sebagai:

A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011

Warna sering disimpan dengan cara ini (dengan byte paling signifikan diabaikan atau digunakan sebagai Alpha):

A = 255 = 11111111
R = 21 = 00010101
G = 255 = 11111111
B = 0 = 00000000
Color = 11111111 00010101 11111111 00000000

Untuk menemukan nilai-nilai lagi, cukup geser bit ke kanan sampai di bagian bawah, lalu sembunyikan bit urutan lebih tinggi yang tersisa:

Int Alpha = Color >> 24
Int Red = Color >> 16 & 0xFF
Int Green = Color >> 8 & 0xFF
Int Blue = Color & 0xFF

0xFFsama dengan 11111111. Jadi pada dasarnya, untuk Red, Anda akan melakukan ini:

Color >> 16 = (filled in 00000000 00000000)11111111 00010101  (removed 11111111 00000000)
00000000 00000000 11111111 00010101 &
00000000 00000000 00000000 11111111 =
00000000 00000000 00000000 00010101 (The original value)

x << n, jadi n harus dalam bentuk nilai 2 ^?
Ahmed C

28

Perlu dicatat bahwa tabel kebenaran bit tunggal yang terdaftar sebagai jawaban lain hanya bekerja pada satu atau dua bit input sekaligus. Apa yang terjadi ketika Anda menggunakan bilangan bulat, seperti:

int x = 5 & 6;

Jawabannya terletak pada ekspansi biner dari setiap input:

  5 = 0 0 0 0 0 1 0 1
& 6 = 0 0 0 0 0 1 1 0
---------------------
      0 0 0 0 0 1 0 0

Setiap pasangan bit di setiap kolom dijalankan melalui fungsi "DAN" untuk memberikan bit output yang sesuai di baris terbawah. Jadi jawaban untuk ungkapan di atas adalah 4. CPU telah melakukan (dalam contoh ini) 8 operasi terpisah "DAN" secara paralel, satu untuk setiap kolom.

Saya menyebutkan ini karena saya masih ingat memiliki "AHA!" saat ketika saya belajar tentang ini bertahun-tahun yang lalu.


Wow, itu jauh lebih masuk akal sekarang. Kedengarannya jauh lebih rumit daripada yang tampaknya. Terima kasih. Saya tidak yakin mana yang harus dipilih sebagai jawaban yang benar karena ada banyak jawaban yang bagus, dan saya tidak dapat menjawabnya dengan baik .. terima kasih
klik

27

Operator bitwise adalah operator yang bekerja sedikit demi sedikit.

DAN adalah 1 hanya jika kedua inputnya adalah 1.

ATAU adalah 1 jika satu atau lebih inputnya adalah 1.

XOR adalah 1 hanya jika salah satu inputnya adalah 1.

BUKAN adalah 1 hanya jika inputnya adalah 0.

Ini dapat digambarkan sebagai tabel kebenaran. Kemungkinan input ada di bagian atas dan kiri, bit yang dihasilkan adalah salah satu dari empat (dua dalam kasus TIDAK karena hanya memiliki satu input) nilai yang ditampilkan di persimpangan dua input.

AND|0 1      OR|0 1
---+----    ---+----
  0|0 0       0|0 1
  1|0 1       1|1 1

XOR|0 1     NOT|0 1
---+----    ---+---
  0|0 1        |1 0
  1|1 0

Salah satu contoh adalah jika Anda hanya ingin 4 bit integer yang lebih rendah, Anda DAN itu dengan 15 (biner 1111) jadi:

    203: 1100 1011
AND  15: 0000 1111
------------------
 IS  11: 0000 1011

16

Ini adalah operator bitwise, semuanya didukung dalam JavaScript:

  • op1 & op2- ANDOperator membandingkan dua bit dan menghasilkan hasil 1 jika kedua bit tersebut 1; jika tidak, ia mengembalikan 0.

  • op1 | op2- OROperator membandingkan dua bit dan menghasilkan hasil 1 jika bit tersebut saling melengkapi; jika tidak, ia mengembalikan 0.

  • op1 ^ op2- EXCLUSIVE-OROperator membandingkan dua bit dan mengembalikan 1 jika salah satu bitnya 1 dan memberikan 0 jika kedua bit tersebut 0 atau 1.

  • ~op1- COMPLEMENTOperator digunakan untuk membalikkan semua bit operan.

  • op1 << op2- SHIFT LEFTOperator memindahkan bit ke kiri, membuang bit paling kiri, dan memberikan bit paling kanan nilai 0. Setiap gerakan ke kiri secara efektif mengalikan op1 dengan 2.

  • op1 >> op2- SHIFT RIGHTOperator memindahkan bit ke kanan, membuang bit paling kanan, dan memberikan bit paling kiri nilai 0. Setiap gerakan ke kanan secara efektif membagi op1 menjadi setengah. Bit tanda paling kiri dipertahankan.

  • op1 >>> op2 - SHIFT RIGHTZERO FILL Operator - memindahkan bit ke kanan, membuang bit paling kanan, dan memberikan bit paling kiri nilai 0. Setiap gerakan ke kanan secara efektif membagi op1 menjadi dua. Bit tanda paling kiri dibuang.


"Jika bitnya saling melengkapi" - apa?
Andrey Tyukin

@AndreyTyukin dua bit saling melengkapi jika salah satunya adalah 1 dan yang lainnya adalah 0.
Jeff Hillman

@JeffHillman Menurut uraian Anda dalam komentar, 1 dan 1 bukan "pelengkap". Maka tidak jelas bagi saya mengapa 1 | 1memberi 1dan tidak 0, dan bagaimana |seharusnya berbeda ^. Saya harus menggunakan Tanya Jawab ini sebagai duplikat target beberapa hari yang lalu, dan saya berharap setelah 10 tahun kita akan memiliki duplikat kanonik yang lebih jelas untuk pertanyaan seperti ini.
Andrey Tyukin

4

Untuk memecahnya sedikit lebih, ini ada hubungannya dengan representasi biner dari nilai yang dimaksud.

Misalnya (dalam desimal):
x = 8
y = 1

akan keluar ke (dalam biner):
x = 1000
y = 0001

Dari sana, Anda dapat melakukan operasi komputasi seperti 'dan' atau 'atau'; pada kasus ini:
x | y =
1000 
0001 |
------
1001

atau ... 9 dalam desimal

Semoga ini membantu.


|itu operasi ATAU?
Si8

Untuk beberapa alasan ini paling masuk akal bagi saya. Masih tidak yakin tentang x | y = 1000 0001 |bagian itu
samayo

4

Ketika istilah "bitwise" disebutkan, kadang-kadang mengklarifikasi bahwa itu bukan operator "logis".

Misalnya dalam JavaScript, operator bitwise memperlakukan operan mereka sebagai urutan 32 bit (nol dan satu) ; Sementara itu, operator logis biasanya digunakan dengan nilai Boolean (logis) tetapi dapat bekerja dengan tipe non-Boolean.

Ambil expr1 && expr2 sebagai contoh.

Mengembalikan expr1 jika dapat dikonversi ke false; jika tidak, kembalikan expr2. Dengan demikian, ketika digunakan dengan nilai-nilai Boolean, && mengembalikan true jika kedua operan benar; jika tidak, mengembalikan false.

a = "Cat" && "Dog"     // t && t returns Dog
a = 2 && 4     // t && t returns 4

Seperti yang telah dicatat orang lain, 2 & 4 adalah bitwise AND, jadi itu akan mengembalikan 0.

Anda dapat menyalin yang berikut ini ke test.html atau sesuatu dan menguji:

<html>
<body>
<script>
    alert("\"Cat\" && \"Dog\" = " + ("Cat" && "Dog") + "\n"
        + "2 && 4 = " + (2 && 4) + "\n"
        + "2 & 4 = " + (2 & 4));
</script>

3

Dalam pemrograman komputer digital, operasi bitwise beroperasi pada satu atau lebih pola bit atau angka biner pada tingkat bit individualnya. Ini adalah tindakan cepat dan primitif yang didukung langsung oleh prosesor, dan digunakan untuk memanipulasi nilai untuk perbandingan dan perhitungan.

operasi :

  • bitwise DAN

  • bitwise ATAU

  • bitwise TIDAK

  • bitor XOR

  • dll

Daftar barang

    AND|0 1        OR|0 1 
    ---+----      ---+---- 
      0|0 0         0|0 1 
      1|0 1         1|1 1 

   XOR|0 1        NOT|0 1 
   ---+----       ---+--- 
     0|0 1           |1 0 
     1|1 0

Misalnya.

    203: 1100 1011
AND  15: 0000 1111
------------------
  =  11: 0000 1011

Penggunaan operator bitwise

  • Operator-operator shift kiri dan shift kanan masing-masing setara dengan perkalian dan pembagian dengan x * 2 y .

Misalnya.

int main()
{
     int x = 19;
     printf ("x << 1 = %d\n" , x <<1);
     printf ("x >> 1 = %d\n", x >>1);
     return 0;
}
// Output: 38 9
  • & Operator dapat digunakan untuk memeriksa dengan cepat apakah suatu angka ganjil atau genap

Misalnya.

int main()
{
    int x = 19;
    (x & 1)? printf("Odd"): printf("Even");
    return 0;
 }
// Output: Odd
  • Cari cepat minimum x dan y tanpa if elsepernyataan

Misalnya.

int min(int x, int y)
{
    return y ^ ((x ^ y) & - (x < y))
}
  • Konversi desimal ke biner

Misalnya.

#include <stdio.h>
int main ()
{
    int n , c , k ;
    printf("Enter an integer in decimal number system\n " ) ;
    scanf( "%d" , & n );
    printf("%d in binary number
    system is: \n " , n ) ;
    for ( c = 31; c >= 0 ; c -- )
    {
         k = n >> c ;
         if ( k & 1 )
              printf("1" ) ;
         else
              printf("0" ) ;
      }
      printf(" \n " );
      return 0 ;
}
  • Enkripsi gerbang XOR adalah teknik yang populer, karena kerumitannya dan digunakan oleh programmer.
  • operator XOR bitwise adalah operator yang paling berguna dari perspektif wawancara teknis.

menggeser bitwise hanya berfungsi dengan nomor + ve

Juga ada berbagai macam penggunaan logika bitwise


"Complixblity dan siapkan ..."?
Jonathan Cross

The left-shift and right-shift operators are equivalent to multiplication and division by x * 2y respectively.Betul sekali! muyiy.cn/question/program/102.html
xgqfrms


1

Mungkin membantu untuk memikirkannya dengan cara ini. Inilah cara AND (&) bekerja:

Pada dasarnya dikatakan keduanya adalah angka-angka ini, jadi jika Anda memiliki dua angka 5 dan 3 mereka akan dikonversi menjadi biner dan komputer akan berpikir

         5: 00000101
         3: 00000011

keduanya satu: 00000001 0 salah, 1 benar

Jadi AND dari 5 dan 3 adalah satu. Operator OR (|) melakukan hal yang sama kecuali hanya satu angka yang harus satu untuk output 1, bukan keduanya.


-5

Saya terus mendengar tentang betapa lambatnya operator bitwise JavaScript. Saya melakukan beberapa tes untuk posting blog terbaru saya dan menemukan mereka 40% hingga 80% lebih cepat daripada alternatif aritmatika dalam beberapa tes. Mungkin mereka dulu lambat. Di browser modern, saya suka mereka.

Saya memiliki satu case dalam kode saya yang akan lebih cepat dan lebih mudah dibaca karena ini. Saya akan terus membuka mata untuk lebih.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.