1. Bitenkénti balra eltolás

A Java-nak is van 3 bitenkénti eltolási operátora : Ha valóban szükséges, akkor nagyon egyszerűen eltolja a szám összes bitjét több pozícióval balra vagy jobbra.

Egy szám bitjeinek balra tolásához szükség van a bitenkénti balra eltolás operátorra . Így van kiírva:

a << b

Hol avan az a szám, amelynek bitjeit eltoljuk, és begy szám, amely azt jelzi, hogy hányszor kell eltolni a szám bitjeit abalra. A művelet során a jobb oldalon hozzáadott alacsony rendű bitek nullák.

Példák:

Példa Eredmény
0b00000011 << 1
0b00000110
0b00000011 << 2
0b00001100
0b00000011 << 5
0b01100000
0b00000011 << 20
0b001100000000000000000000

Ha egy számjegyet balra tolunk, az ugyanolyan hatással jár, mint egy szám 2-vel való szorzása.

Meg akar szorozni egy számot 16-tal? A 16 ugyanaz, mint a 2 4 . Tehát eltolja a számot 4 számjegyet balra


2. Bitenkénti eltolás jobbra

A bitek jobbra is eltolhatók. Ehhez használja a bitenkénti jobbra eltolás operátort . Így van kiírva:

a >> b

Hol avan az a szám, amelynek bitjeit eltoljuk, és baz, hogy hányszor kell a szám bitjeit ajobbra tolni.

Példák:

Példa Eredmény
0b11000011 >> 1
0b01100001
0b11000011 >> 2
0b00110000
0b11000011 >> 5
0b00000110
0b11000011 >> 20
0b00000000

Ha egy számjegyet jobbra tolunk, akkor az ugyanazt a hatást éri el, mintha egy számot osztana 2-vel.

A művelet során a bal oldalra hozzáadott magasabb rendű bitek nullák, de nem mindig !

Fontos!

Az előjeles szám bal szélső bitjét előjelbitnek nevezzük : ha a szám pozitív, akkor az 0; de ha a szám negatív, akkor ez a bit 1.

Egy szám bitjeinek jobbra tolásakor rendszerint az előjelbit értéke is eltolódik, és a szám előjele elveszne. Ennek megfelelően negatív számok esetén (ahol a bal szélső bit 1) ez a bit különleges bánásmódban részesül. Ha egy szám bitjeit jobbra tolja, akkor a 0bal oldalra ad hozzá, ha a bal szélső bit volt 0, és a 1hozzáadódik a bal oldalhoz, ha a bal szélső bit volt 1.

De a fenti példában úgy tűnik, hogy nem ez az eredmény. Miért? Mivel az egész literálok ints-ek, és  valójában azt jelentik . Vagyis a bal szélső bit nulla.0b111111110b00000000000000000000000011111111

Sok programozót frusztrált ez a jobbra váltó viselkedés, és azt szeretné, ha a szám mindig nullákkal lenne kitöltve. Tehát a Java hozzáadott egy másik jobbra váltó operátort .

Így van kiírva:

a >>> b

Hol a van az a szám, amelynek bitjeit eltoljuk, és b  az, hogy hányszor kell a szám bitjeit ajobbra tolni. Ez az operátor mindig nullákat fűz a bal oldalra, függetlenül a szám előjelbitjének eredeti értékétől a.



3. Zászlókkal való munka

A programozók szinte teljesen új tudományterületet hoztak létre a bitenkénti és shift műveletek alapján: a zászlókkal való munkát.

Amikor a számítógépeknek nagyon kevés memóriája volt, nagyon népszerű volt sok információt egyetlen számba zsúfolni. Egy számot bittömbként kezeltünk: az int 32 bites, a long pedig 64 bites.

Egy ilyen számba sok információt lehet írni, főleg ha logikai ( truevagy false) értékeket kell tárolni. Az egyetlen longolyan, mint egy boolean64 elemből álló tömb. Ezeket a biteket zászlóknak nevezték , és a következő műveletekkel manipulálták:

  • állítsa be a zászlót
    (egy meghatározott bit legyen egyenlő a -val 1)
  • reset flag
    (egy meghatározott bit legyen egyenlő a -val 0)
  • ellenőrző zászló
    (ellenőrizze egy adott bit értékét)

És itt van ez a bitenkénti operátorokkal.

Zászló felállítása

Egy adott bit értékre állításához 1bitenkénti VAGY műveletet kell végrehajtani a beállítani kívánt szám és egy speciálisan létrehozott szám között, ahol csak az a bit 1.

Tegyük fel például, hogy megvan a szám 0b00001010, és az 5. bitet értékre kell állítania 1. Ebben az esetben a következőket kell tennie:

0b00001010 | 0b00010000 = 0b00011010

Ha az 5. bit már egyre lett volna állítva, akkor semmi sem változott volna.

Általában a zászló beállításának művelete a következőképpen írható fel

a | (1 << b)

Hol a van az a szám, amelynek bitje 1. És b a beállítandó bit helyzete. A bal shift operátor használata itt rendkívül kényelmes, hiszen azonnal megtudhatja, melyik bittel dolgozunk.

Zászló visszaállítása

Egy adott bit alaphelyzetbe állításához (azaz értékre állításához 0) anélkül, hogy más biteket megzavarnánk, egy műveletet kell végrehajtani &a visszaállítani kívánt szám (azaz értékre állítani 0) és egy speciálisan létrehozott szám között, ahol az összes bit egyenlő, 1kivéve a visszaállítani kívánt bithez.

Tegyük fel például, hogy megvan a szám 0b00001010, és a 4. bitet értékre kell állítania 0. Ebben az esetben a következőket kell tennie:

0b00001010 & 0b11110111 = 0b00000010

Ha a 4. bit már nullára lett volna állítva, akkor semmi sem változott volna.

Általában a zászló visszaállításának művelete a következőképpen írható fel

a & ~(1 << b)

Hol a van az a szám, amelynek bitje vissza lesz állítva 0. És b a törlendő bit helyzete.

Ahhoz, hogy olyan számot kapjunk, amelyben minden bit van, 1kivéve azt, amelyet nullának szeretnénk tenni, először 1 b  pozíciót tolunk balra, majd a bitenkénti NOToperátorral invertáljuk az eredményt.

Zászló ellenőrzése

Egy adott jelző beállításán vagy visszaállításán kívül néha csak azt kell ellenőrizni, hogy egy adott jelző be van-e állítva, azaz egy bizonyos bit egyenlő-e a -val 1. Ez elég könnyen megtehető egy bitwise &.

Tegyük fel például, hogy ellenőriznie kell, hogy a 4. bit értékre van-e állítva 1a számban 0b00001010. Akkor ezt kell tenned:

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

Általában a zászló ellenőrzésének művelete a következőképpen írható fel

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

Hol a van az a szám, amelynek bitjét ellenőrzik. És b ellenőrizni kell a bit helyzetét.


4. Titkosítás

A bitenkénti XORműveletet a programozók gyakran használják egyszerű titkosításra. Általában az ilyen titkosítás így néz ki:

result = number ^ password;

Hol number van a titkosítani kívánt adat, password egy speciális szám, amelyet "jelszóként" használnak az adatokhoz, és result ez a titkosított szám.

number == (number ^ password) ^ password;

Itt az a fontos, hogy amikor az XORoperátort kétszer alkalmazzuk egy számra, akkor a „jelszótól” függetlenül az eredeti számot állítja elő.

number A hiba helyreállításához encrypted resultcsak ismételje meg a műveletet:

original number = result ^ password;

Példa:

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));
   }
}