1. Anjakan kiri bitwise

Java juga mempunyai 3 operator anjakan bitwise : Jika anda benar-benar perlu, anda boleh mengalihkan semua bit nombor beberapa kedudukan ke kiri atau kanan.

Untuk mengalihkan bit nombor ke kiri, anda memerlukan operator anjakan kiri bitwise . Ini adalah bagaimana ia ditulis:

a << b

Di manakah anombor yang bitnya dialihkan, dan bmerupakan nombor yang menunjukkan berapa kali untuk mengalihkan bit nombor itu ake kiri. Semasa operasi ini, bit tertib rendah yang ditambahkan di sebelah kanan ialah sifar.

Contoh:

Contoh Hasilnya
0b00000011 << 1
0b00000110
0b00000011 << 2
0b00001100
0b00000011 << 5
0b01100000
0b00000011 << 20
0b001100000000000000000000

Mengalihkan satu digit ke kiri mempunyai kesan yang sama seperti mendarab nombor dengan 2.

Ingin mendarab nombor dengan 16? 16 sama dengan 2 4 . Jadi anda mengalihkan nombor 4 digit ke kiri


2. Anjakan bitwise ke kanan

Bit juga boleh dialihkan ke kanan. Untuk melakukan ini, gunakan operator anjakan kanan bitwise . Ini adalah bagaimana ia ditulis:

a >> b

Di manakah anombor yang bitnya dialihkan, dan bialah bilangan kali untuk mengalihkan bit nombor itu ake kanan.

Contoh:

Contoh Hasilnya
0b11000011 >> 1
0b01100001
0b11000011 >> 2
0b00110000
0b11000011 >> 5
0b00000110
0b11000011 >> 20
0b00000000

Peralihan satu digit ke kanan mempunyai kesan yang sama seperti membahagikan nombor dengan 2.

Semasa operasi ini, bit tertib tinggi yang ditambahkan di sebelah kiri adalah sifar, tetapi tidak selalu !

Penting!

Bit paling kiri bagi nombor yang ditandatangani dipanggil bit tanda : jika nombor itu positif, ia adalah 0; tetapi jika nombornya negatif, bit ini ialah 1.

Apabila mengalihkan bit nombor ke kanan, nilai bit tanda biasanya akan turut beralih dan tanda nombor itu akan hilang. Sehubungan itu, untuk nombor negatif (di mana bit paling kiri ialah 1), bit ini mendapat layanan istimewa. Apabila mengalihkan bit nombor ke kanan, a 0ditambah di sebelah kiri jika bit paling kiri ialah 0, dan a 1ditambah di sebelah kiri jika bit paling kiri ialah 1.

Tetapi dalam contoh di atas, itu nampaknya bukan hasilnya. kenapa? Kerana literal integer ialah ints, dan  sebenarnya bermaksud . Iaitu, bit paling kiri ialah sifar.0b111111110b00000000000000000000000011111111

Ramai pengaturcara kecewa dengan tingkah laku anjakan kanan ini dan lebih suka nombor itu sentiasa diisi dengan sifar. Jadi Java menambah satu lagi operator anjakan kanan .

Ini adalah bagaimana ia ditulis:

a >>> b

Di manakah a nombor yang bitnya dialihkan, dan b  ialah bilangan kali untuk mengalihkan bit nombor itu ake kanan. Operator ini sentiasa menambahkan sifar di sebelah kiri, tanpa mengira nilai asal bit tanda nombor a.



3. Bekerja dengan bendera

Pengaturcara mencipta bidang pengajian yang hampir sepenuhnya baharu berdasarkan operasi bitwise dan shift: bekerja dengan bendera.

Apabila komputer mempunyai ingatan yang sangat sedikit, ia sangat popular untuk menjejalkan banyak maklumat ke dalam satu nombor. Nombor telah dianggap sebagai tatasusunan bit: int ialah 32 bit, dan panjang ialah 64 bit.

Anda boleh menulis banyak maklumat dalam nombor sedemikian, terutamanya jika anda perlu menyimpan nilai logik ( trueatau false). Satu longadalah seperti booleantatasusunan yang terdiri daripada 64 elemen. Bit ini dipanggil bendera dan dimanipulasi menggunakan operasi berikut:

  • menetapkan bendera
    (buat bit tertentu sama dengan 1)
  • set semula bendera
    (buat bit tertentu sama dengan 0)
  • semak bendera
    (semak nilai bit tertentu)

Dan inilah cara ia dilakukan dengan pengendali bitwise.

Menetapkan bendera

Untuk menetapkan bit tertentu kepada 1, anda perlu melakukan operasi OR bitwise antara nombor yang bitnya anda ingin tetapkan dan nombor yang dicipta khas, di mana hanya bit itu 1.

Sebagai contoh, katakan anda mempunyai nombor 0b00001010dan anda perlu menetapkan bit ke-5 kepada 1. Dalam kes itu, anda perlu:

0b00001010 | 0b00010000 = 0b00011010

Jika bit ke-5 telah ditetapkan kepada satu, maka tiada apa yang akan berubah.

Secara umum, operasi menetapkan bendera boleh ditulis seperti berikut

a | (1 << b)

Di manakah a nombor yang bit akan ditetapkan kepada 1. Dan b adalah kedudukan bit yang akan ditetapkan. Menggunakan operator syif kiri adalah sangat mudah di sini, kerana anda boleh segera mengetahui bit mana yang sedang kami gunakan.

Menetapkan semula bendera

Untuk menetapkan semula bit tertentu (iaitu tetapkannya kepada 0) tanpa mengganggu bit lain, anda perlu melakukan operasi &antara nombor yang bitnya anda ingin tetapkan semula (iaitu ditetapkan kepada 0) dan nombor yang dicipta khas, di mana semua bit adalah sama dengan 1kecuali untuk bit yang anda mahu tetapkan semula.

Sebagai contoh, katakan anda mempunyai nombor 0b00001010dan anda perlu menetapkan bit ke-4 kepada 0. Dalam kes itu, anda perlu:

0b00001010 & 0b11110111 = 0b00000010

Jika bit ke-4 telah ditetapkan kepada sifar, maka tiada apa yang akan berubah.

Secara umum, operasi menetapkan semula bendera boleh ditulis seperti berikut

a & ~(1 << b)

Di manakah a nombor yang bitnya akan ditetapkan semula kepada 0. Dan b adakah kedudukan bit yang perlu dibersihkan.

Untuk mendapatkan nombor di mana semua bit adalah 1kecuali yang kita mahu menjadi sifar, kita mula-mula mengalihkan kedudukan 1 b  ke kiri, dan kemudian menggunakan NOToperator bitwise untuk menyongsangkan hasilnya.

Menyemak bendera

Selain menetapkan atau menetapkan semula bendera tertentu, kadangkala anda hanya perlu menyemak sama ada bendera yang diberikan ditetapkan, iaitu sama ada bit tertentu sama dengan 1. Ini agak mudah dilakukan dengan bitwise &.

Sebagai contoh, katakan anda perlu menyemak sama ada bit ke-4 ditetapkan 1pada nombor 0b00001010. Kemudian anda perlu melakukan ini:

if ( (0b00001010 & 0b00001000) == 0b00001000 )

Secara umum, operasi menyemak bendera boleh ditulis seperti berikut

(a & (1 << b)) == (1 << b)

Mana a ada nombor yang bitnya sedang disemak. Dan b adakah kedudukan bit yang perlu diperiksa.


4. Penyulitan

Operasi bitwise XORsering digunakan oleh pengaturcara untuk penyulitan mudah. Secara umum, penyulitan sedemikian kelihatan seperti ini:

result = number ^ password;

Di manakah number data yang ingin kami enkripsi, password adalah nombor khas yang digunakan sebagai "kata laluan" untuk data, dan result merupakan nombor yang disulitkan.

number == (number ^ password) ^ password;

Perkara penting di sini ialah apabila XORpengendali digunakan pada nombor dua kali, ia menghasilkan nombor asal, tanpa mengira "kata laluan".

Untuk memulihkan number daripada encrypted result, anda hanya perlu melakukan operasi semula:

original number = result ^ password;

Contoh:

class Solution
{
   public static int[] encrypt(int[] data, int password)
   {
     int[] result = new int[data.length];
     for (int i = 0; i <  data.length; i++)
       result[i] = data[i] ^ password;
     return result;
   }

   public static void main(String[] args)
   {
     int[] data =  {1, 3, 5, 7, 9, 11};
     int password = 199;

     // Encrypt the array of data
     int[] encrypted = encrypt(data, password);
     System.out.println(Arrays.toString(encrypted));

     // Decrypt the array of data
     int[] decrypted = encrypt(encrypted, password);
     System.out.println(Arrays.toString(decrypted));
   }
}