Zielony Smok - logo witryny

Maskowanie bitów (Java)

Maska 2-bitowa

Do maskowania użyjemy operatora iloczynu bitowego &.

Mamy dwie zmienne;

int x = 21, czyli (10110)2

int maska = 2, czyli (10)2

Po zastosowaniu maski:

x = x & maska

albo

x &= maska

otrzymujemy wynik

x = 2

Możemy to rozpisać w tablicy.

1 0 1 1 1
        &
0 0 0 1 0
        =
0 0 0 1 0

Wszystkie bity na lewo do ostatniej jedynki (1) w masce są zawsze zerami, niezależnie od tego ile bitowa jest sama liczba.

Z logiki wiemy, że koniunkcja zwraca true (1) tylko wtedy gdy obie strony koniunkcji mają wartość true (1).

W pozostałych przypadkach zwraca false (0). To oznacza, że faktycznie ważne sa tylko te miejsca liczby w których maska ma liczbę 1 i tylko te bity liczby znajdą się w wyniku.

Po wykonaniu maskowania wynik ma tyle bitów ile miała maska. W naszym przypadku 2 bity, czyli (10)2 i jest to liczba 2.

Kod Java:

package binaria;

public class BinAria02 {
	public static void main(String[] args) {
		int a = 22;
		System.out.println(Integer.toBinaryString(a));
		int b = 2;
		System.out.println(Integer.toBinaryString(b));
		a = (byte)(a & b);
		System.out.println(a);
	}
}

Po uruchomieniu na konsoli zobaczymy:

10110
10
2

Maska 1-bitowa

Sprawdzanie parzystości Java jest przykładem użycia maski (1)2

Maska 8-bitowa

Bardzo często używa się maski do wycięcia z liczby np. 32-bitowej ostatnich 8 bitów:

x &= 0377, czyli (11111111)2. (Czołowe 0 oznacza, że liczba jest ósemkowa). Można oczywiście 🙂 zastosować maskę (255)10

   int a = 1234567;
   System.out.println(Integer.toBinaryString(a));
   int b = 0377;
   System.out.println(Integer.toBinaryString(b));
   a = (int) (a & b);
   System.out.println(a);
   System.out.println(Integer.toBinaryString(a));

Po uruchomieniu kodu (BinAria03.java) na konsoli otrzymamy

100101101011010000111
11111111
135
10000111

Maska 8-bitowa przesuwna

W języku Java kolor mozna wyrażać pojedynczą liczbą int.

Przykładem może być 'kolor koloru koralowego’ 🙂 czyli (16744272)10 = (111111110111111101010000)2
= (ff7f50)16.

 

Powstaje pytanie jak odczytać wartości składowe koloru rgb (red, green, blue). Użyjemy operatora bitowego przesunięcia w prawo oraz maski (0377), składającej się binarnie z 8 jedynek.

Dla blue nie ma przesunięcia, dla green przesuniecie wynosi 8, dla red przesunięcie wynosi 16.

A oto stosowny kod (BinAria04.java);

   int rgb = 16744272;
   System.out.println(Integer.toBinaryString(rgb));
   int maska = 0377;
   int r = (rgb >> 16) & maska;
   int g = (rgb >> 8) & maska;
   int b = (rgb >> 0) & maska;
   System.out.println("r = " + r + " = " + Integer.toBinaryString(r));
   System.out.println("g = " + g + " = 0" + Integer.toBinaryString(g));
   System.out.println("b = " + b + " = 0" + Integer.toBinaryString(b));
   System.out.println(Integer.toHexString(rgb));

Po uruchomieniu tego kodu na konsoli zobaczymy:

111111110111111101010000
r = 255 = 11111111
g = 127 = 01111111
b = 80 = 01010000
ff7f50

Maska hexa

Maska może być liczbą heksadecymalną.

(0377)8 = (0xff)16

A oto powyższy przykład nieco przerobiony (BinAria05.java):

   int rgb = 16744272;
   System.out.println(Integer.toBinaryString(rgb));
   int r = (rgb >> 16) & 0xff;
   int g = (rgb >> 8) & 0xff;
   int b = (rgb >> 0) & 0xff;
   System.out.println(r);
   System.out.println(g);
   System.out.println(b);

Po uruchomieniu kodu na konsoli otrzymujemy:

   111111110111111101010000
   255
   127
   80