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 a
van az a szám, amelynek bitjeit eltoljuk, és b
egy szám, amely azt jelzi, hogy hányszor kell eltolni a szám bitjeit a
balra. A művelet során a jobb oldalon hozzáadott alacsony rendű bitek nullák.
Példák:
Példa | Eredmény |
---|---|
|
|
|
|
|
|
|
|
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 a
van az a szám, amelynek bitjeit eltoljuk, és b
az, hogy hányszor kell a szám bitjeit a
jobbra tolni.
Példák:
Példa | Eredmény |
---|---|
|
|
|
|
|
|
|
|
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 !
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 0
bal oldalra ad hozzá, ha a bal szélső bit volt 0
, és a 1
hozzá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 int
s-ek, és valójában azt jelentik . Vagyis a bal szélső bit nulla.0b11111111
0b00000000000000000000000011111111
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 a
jobbra 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 ( true
vagy false
) értékeket kell tárolni. Az egyetlen long
olyan, mint egy boolean
64 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 1
bitenké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ő, 1
kivé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, 1
kivéve azt, amelyet nullának szeretnénk tenni, először 1 b pozíciót tolunk balra, majd a bitenkénti NOT
operá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 1
a 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 XOR
mű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 XOR
operá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 result
csak 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));
}
}
GO TO FULL VERSION