Bit műveletek



Kezdjük a biteknél. Mi is a bit? A kettes számrendszerbe átültetett adat (Bináris adaT) legkisebb egysége. A bit két értéket vehet fel: egy alacsony állapotot amit Low-al vagy 0-val jelölünk illetve egy magas állapotot ami High vagy 1 értékű. 8Bit ad 1byte-ot ez egy nyolc számjegyű bináris számnak felel meg. A bináris számokba nem akartam belefolyni de minimálisan azért muszáj megemlítenem a felépítésüket.

Kezdjük az elején: vegyünk egy három számjegyű decimális (tízes számrendszerű) számot, legyen
ez mondjuk a 234. Ha felosszuk a számot helyi értéknek megfelelő egységekre akkor ezt kapjuk:

2db 100-as = 2 x 10 x 10 (kétszer 10 a másodikon) +
3db 10-es = 3x 10 (háromszor 10 az elsőn) +
4db 1-es =4x 1 (négyszer 10 a nulladikon) = 234

A bináris szám ugyan így működik, csak a kettes hatványait használja helyi értékekként.
Nézzünk egy bináris számot(felbontás balról jobbra): 1101
1db 8-as = 1 x 2 x 2 x 2 (egyszer 2 a harmadikon) +
1db 4-es = 1 x 2 x 2 (egyszer 2 a másodikon) +
0db 2-es = 0 x 2 (nullaszor 2 az elsőn) +
1db 1-es = 1 x 1 (egyszer 2 a nulladikon) = 1101 = 8+4+1 = 13 decimálisan.


Remélem ez így érthető volt. A bit műveletek amikről ez a cikk szól, pont ezeknek a számoknak a kezelésével foglalkozik. Nézzük rögtön az első függvényünket:

bit(n) – a bit n-edik értékét adja(a kettő n-edik hatványát).
pl.: n = 2 a függvény visszatérési értéke 2 a másodikon vagyis 4
ha n = 3 akkor a visszatérési 2 a harmadikon vagyis 8, és így tovább....

void setup(){
Serial.begin(9600);
}
void loop(){
for(int n = 0;n<8;n++){
Serial.print(n+1);
Serial.print(" bites szam ");
Serial.print(bit(n)*2);
Serial.println(" erteket vehet fel.");
delay(500);
}
while(1);
}

A rövidke programban kiíratjuk 1-től 8 számjegyig terjedő bináris szám max. értékeit.
A következő sorról még: Serial.print(bit(n)*2); azért szorozzuk meg a bit(n) művelet értékét kettővel mert csak a kettő n-edik hatványát adja, vagyis a bináris számból az n-edik számjeggyel jelölhető legnagyobb értéket (jobbról balra számolva), az előző számjegyek összeadott bináris értéke plusz 1 (a nulla) pont megegyezik ezzel a számmal. Így csak ezt kell megszoroznunk kettővel ahhoz, hogy megkapjuk az adott számjegyű bináris szám max. értékét.

Példa: 4jegyű bináris szám max. értéke 1111, ez lebontásban
1db 8-as, 1db 4-es, 1db 2-es, 1db 1-es = 8+4+2+1 =15 (a 16. érték a 0000) 8 x 2 = 16

A következő függvény: bitSet() – egy szám meghatározott bitjét 1-re állítja.
Pl.: bitSet(x,n);
x: egy adott szám
n: a szám bitje aminek 1-es értéket adunk.

Ide tartozik a bitClear() – egy szám meghatározott bitjének értékét törli(0-ra állítja)
pl.: bitClear(x,n);
x: egy adott szám
n: a szám törlendő bitje


void setup(){
Serial.begin(9600);
}
void loop(){
byte szam = 25;
Serial.print(szam);
Serial.println(" decimalis szam binaris erteke: ");
Serial.println(szam,BIN);
bitSet(szam,1);
Serial.println("a bitSet() utasitas utani binaris ertek: ");
Serial.println(szam,BIN);
Serial.println("a bitSet() utani decimalis ertek:");
Serial.println(szam);
bitClear(szam,4);
Serial.println("a bitClear() utasitas utani binaris ertek: ");
Serial.println(szam,BIN);
Serial.println("a bitClear() utani decimalis ertek:");
Serial.println(szam);
while(1);
}


A progiban a bitSet() utasítással 25 bináris értékének 1-es bitjét(2) állítottuk át 1-es értékre, így +2 hozzáadódott a decimális értékhez (27).

A bitClear() utasítással 27 4-es bitjét (16) nulláztuk le így 16-ot elvettünk a decimális értékből, az
eredmény decimálisan 11 lett.
Azt hiszem ez érthető így, tovább léphetünk a következő utasításokra:

bitRead() – egy adott szám adott bitjének értékét olvassa ki.
pl.:bitRead(x,n);
x: egy adott szám
n: a szám n-edik bitje

a visszatérési érték 0 vagy 1 az adott bit értékétől függően.

bitWrite() – egy szám adott bitjét írja át a megadott értékre.
pl.: bitWrite(x,n,b);
x: adott szám
n: a szám megadott bitje
b: a megadott beírandó bit értéke (0 vagy 1).


Az utolsó két függvény bájtok kezelésében segít. Nézzük:
highByte() -- egy kétbájtos szám felső bájtját adja vagy kettőnél több bájtos
számnál a második legkisebb helyiértékű bájttal tér vissza.
pl.: highByte(x);
x: egy két vagy több bájtos szám aminek felső bájtját adja vissza a függvény

lowByte() -- egy kétbájtos szám alsó bájtját adja vissza.

pl.: lowByte(x);
x: egy két bájtos szám.

Lássunk egy példa progit:

unsigned int szam;
void setup(){
Serial.begin(9600);
}
void loop(){
szam = 32768 ;
byte h_b, l_b;
h_b = highByte(szam);
l_b = lowByte(szam);
Serial.print(szam);
Serial.println(" binaris erteke: ");
Serial.println(szam,BIN);
Serial.print("felso bajtjanak erteke: ");
Serial.println(h_b,BIN);
Serial.print("also bajtjanak erteke: ");
Serial.println(l_b,BIN);
while(1);
}


Az első ami fontos a 2 bájtos szám 16 bitből áll, de nem előjellel, ezért használunk előjel nélküli int-et( így mind a 16 bit kihasználható).
A progiban megadott decimális szám bináris értékének alsó bájtját(jobb oldali 8 bitjét) adja a lowByte() függvény.
A highByte() a decimális szám bináris értékének második (jobbról) bájtját adja, ez két bájtos számnál a felső bájt.
Ha megnézzük a szám változó által tárolt szám bináris értékét, két dolgot vehetünk észre: először a szám csak 15 számjegyű, ez azért van mert a bináris kiíratásnál a szám elején lévő nullák nem kerülnek kiíratásra. pl.:001101 = 1101
A második: a szám minden bitje 1 (32767), ez a 2 a 15.-en, pontosabban 2 a nulladiktól 2 a 14.-ig hatványok összeadott értéke.
Változtassuk meg a szám értékét 32768-ra. A bináris szám 16 jegyű lesz, 1-el kezdődik és 15 nulla követi. Ebből a lowByte nulla , a highByte 10000000 lesz.


Gyakorlatban bit alapon működik szinte minden, nagy szerencsénkre elrejti a fejlesztői környezet,
de néha még is használunk kell egyik másik eszköznél.