Operátorok

A mütyűrködés csúcsa: a bitoperátorok

 

Bevezetés

Bitenkénti NOT

Bitenkénti AND

Bitenkénti OR

Bitenkénti XOR

Biteltolás balra

Biteltolás jobbra

 

Bevezetés

 

A számítógép segítségével rengetegféle művelet elvégezhető, sőt a valóság milliónyi aspektusa modellezhető le. Ennek ellenére bevallom őszintén a jelenlegi tudásommal fogalmam sincs, hogy az alábbi bitműveleteket milyen konkrét probléma megoldására lehetne alkalmazni. Az általam olvasott Java-oktatási anyagok legtöbbjében nem szerepelnek vagy csak az operátorok között, felsorolás szintjén. A legkiterjedtebb magyarázatot Angster Erzsébet Objektumorientált tervezés és programozás, JAVA, 1. kötet című munkájában olvastam (197. oldal), bár ő sem tért ki a bitoperálás lehetséges alkalmazásaira.

 

Az mindenesetre bizonyos, hogy talán az egyik leggyorsabban elvégezhető műveletfajtával van dolgunk, mert nem hiszem, hogy a számítógépben műveletileg bármi is gyorsabb lehet 1 bit átállításánál. (Persze az is számít, hogy mely hardveren kell ezt megtennünk, hiszen mondjuk egy hagyományos HDD válaszideje messze alulmarad a műveleti memória válaszidejétől, a processzor regisztereiről nem is beszélve.)

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

Először nézzük meg a bitműveletek szintaktikai szimbólumait (a témához kapcsolódó alapfogalmak az Igazságtáblák című fejezetben tanulmányozhatók):

Ezután nincs más dolgunk, mint a bitmütyűrködést leellenőrizni futtatható kódokon keresztül. Kiindulópontunk a decimális 8 lesz, amely binárisan fogalmazva 1000. Tehát:

 

8dec = 1000bin

 

Először ellenőrizzük le állításunkat az Integer.toBinaryString() függvény segítségével, amely int típusú decimális számot binárissá, majd String típussá alakít át:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    }
}
 

Végeredmény:

1000

 

~ - bitenkénti NOT

 

A luciferi tagadás bitművelete, csakis 1 operandust igényel:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(~szam));
    }
}
 

Végeredmény:

11111111111111111111111111110111

 

Mi is történt?

A bitenkénti tagadás művelete végrehajtásra került, azonban az int adattípus teljes tárolási tartományára, azaz mind a 32 bitre (emlékezzünk vissza erre az értékre a Numerikus egész című fejezetből). Ez mutatja azt, hogy int (és persze más) adattípus esetén is a rendszer az összes dedikált memóriaterületet valóban lefoglalja. Észrevehetjük a sor jobb végén az 1000 "tagadását", ami 0111.

 

& - bitenkénti AND

 

A bitművelet már 2 operandust igényel, vizsgálatához először nézzük meg igazságtábláját:

 

www.informatika-programozas.hu - logikai kapu - AND

 

Az AND logikai művelet kimenete csakis akkor ad 1 (true) értéket, ha mindkét bemenet szintén 1. Ha a művelet második operandusának például a decimális 1 számot választjuk...

 

8dec = 1000bin

1dec = 0001bin

 

...akkor láthatjuk, hogy a 2 szám logikai AND műveletű összefuttatásakor nem lesz sehol közös 1 bit, ezért a végeredmény 0 lesz. A könnyebb olvashatóság érdekében ezt a szam3 nevű változóba tettük (int szam3 = szam & szam2;):

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    int szam2 = 1;
    System.out.println(Integer.toBinaryString(szam2));
    int szam3 = szam & szam2;

    System.out.println(szam3);
    System.out.println(Integer.toBinaryString(szam3));
    }
}
 

Végeredmény:

1000

1

0

0

 

De ha a művelet második operandusának például a decimális 8 számot választjuk...

 

8dec = 1000bin

8dec = 1000bin

 

...akkor láthatjuk, hogy a 2 szám logikai AND műveletű összefuttatásakor lesz 1 db közös 1 bit, ezért a végeredmény szintén decimális 8 lesz:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    int szam2 = 8;
    System.out.println(Integer.toBinaryString(szam2));
    int szam3 = szam & szam2;

    System.out.println(szam3);
    System.out.println(Integer.toBinaryString(szam3));
    }
}
 

Végeredmény:

1000

1000

8

1000

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

Azt is láthatjuk, hogy a Java-konzol a bináris kiírást egyszerűsíti, hiszen az üres 0 biteket nem írta ki, ezek az 1-től balra szereplő bitek összesen 32 bit terjedelemben.

 

| - bitenkénti OR

 

Ez a bitművelet szintén 2 operandust igényel, vizsgálatához először nézzük meg igazságtábláját:

 

www.informatika-programozas.hu - logikai kapu - AND

 

Az OR logikai művelet kimenete csakis akkor ad 1 (true) értéket, ha valamelyik bemeneten találunk 1 bitet. Ha a művelet második operandusának például a decimális 1 számot választjuk...

 

8dec = 1000bin

1dec = 0001bin

 

...akkor a 2 szám logikai OR műveletű összefuttatásakor a végeredmény 1001 lesz, amely decimális 9 számnak felel meg:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    int szam2 = 1;
    System.out.println(Integer.toBinaryString(szam2));
    int szam3 = szam | szam2;

    System.out.println(szam3);
    System.out.println(Integer.toBinaryString(szam3));
    }
}
 

Végeredmény:

1000

1

9

1001

 

^ - bitenkénti XOR

 

Ez a bitművelet szintén 2 operandust igényel, vizsgálatához először nézzük meg igazságtábláját:

 

www.informatika-programozas.hu - logikai kapu - XOR

 

A XOR logikai művelet kimenete csakis akkor ad 1 (true) értéket, ha kizárólag az 1 bemeneten megjelenik 1 true bit. Ha a művelet második operandusának például a decimális 13 számot választjuk...

 

8dec = 1000bin

13dec = 1101bin

 

...akkor a 2 szám logikai XOR műveletű összefuttatásakor a végeredmény 101 lesz, amely decimális 5 számnak felel meg:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    int szam2 = 1;
    System.out.println(Integer.toBinaryString(szam2));
    int szam3 = szam ^ szam2;

    System.out.println(szam3);
    System.out.println(Integer.toBinaryString(szam3));
    }
}
 

Végeredmény:

1000

1101

5

101

 

<< - biteltolás balra

 

A művelet alapjában véve 1 operandusú, de Javában kötelezően meg kell adnunk az eltolás mértékét is, például 1-es eltolás esetén: szam << 1. A művelet végrehajtásakor tehát azt várjuk, hogy például decimális 8 számból...

 

8dec = 1000bin

 

...10000 legyen, ami decimális 16-nak felel meg:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    int szam2 = szam << 1;
    System.out.println(szam2);
    System.out.println(Integer.toBinaryString(szam2));
    }
}
 

Végeredmény:

1000

16

10000

 

De például 2-es eltolás esetén az eredmények is eszerint fognak változni:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    int szam2 = szam << 2;
    System.out.println(szam2);
    System.out.println(Integer.toBinaryString(szam2));
    }
}
 

Végeredmény:

1000

32

100000

 

>> - biteltolás jobbra

 

A művelet alapjában véve 1 operandusú, de kötelezően meg kell adnunk az eltolás mértékét is, például 1-es eltolás esetén: szam >> 1. A művelet végrehajtásakor tehát azt várjuk, hogy például decimális 8 számból...

 

8dec = 1000bin

 

...100 legyen, ami decimális 4-nek felel meg:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    int szam2 = szam >> 1;
    System.out.println(szam2);
    System.out.println(Integer.toBinaryString(szam2));
    }
}
 

Végeredmény:

1000

4

100

 

De például 2-es eltolás esetén az eredmények is eszerint fognak változni:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int szam = 8;
    System.out.println(Integer.toBinaryString(szam));
    int szam2 = szam >> 2;
    System.out.println(szam2);
    System.out.println(Integer.toBinaryString(szam2));
    }
}
 

Végeredmény:

1000

2

10