Bitové pole ( angl. bit field ) v programování - množství bitů uspořádaných za sebou v paměti , jejichž hodnotu není procesor schopen přečíst kvůli zvláštnostem hardwarové implementace .
Pokud je potřeba přečíst hodnotu zapsanou do paměťového umístění , procesor provede následující akce:
Načtená hodnota se rovná hodnotě v zadaném paměťovém místě a má velikost rovnou šířce datové sběrnice ( velikost slova stroje ).
Šířka adresové sběrnice určuje minimální velikost adresovatelné paměti . Řadič paměti vyžaduje, aby adresa buňky byla zarovnána na hranici slova stroje .
Pokud se bitová šířka (počet bitů) čtené hodnoty (bitového pole) nerovná velikosti strojového slova , po načtení strojového slova z paměti je třeba provést další instrukce :
Příklad. Nechat:
Pokud adresa hodnoty, která má být načtena z paměti , není zarovnána na hranici slova stroje , jsou vyžadovány další kroky:
Příklad. Nechat:
Lze provést další popsané kroky:
Nevýhoda: další příkazy zpomalují provádění programu . Výhoda: při použití bitových polí je dosaženo nejhustšího sbalení informací .
Kompilátory obecně umožňují pouze následující operace s bitovými poli:
Samotné bitové pole je kompilátorem považováno za číslo bez znaménka . Pořadí bitových polí v datové struktuře závisí na hardwarové platformě a implementaci kompilátoru : některé kompilátory umísťují bitová pole počínaje nejméně významnými bity, zatímco jiné je umísťují od nejvýznamnějších.
Bitová pole se používají pro nejúplnější balení informací , pokud není důležitá rychlost přístupu k těmto informacím. Například ke zvýšení šířky pásma kanálu při přenosu informací po síti nebo ke snížení velikosti informací během ukládání. Také použití bitových polí má své opodstatnění, pokud procesor podporuje specializované instrukce pro práci s bitovými poli a kompilátor tyto instrukce používá při generování strojového kódu .
Například na počítačích s 32bitovým slovem budou všechna pole v paketu IPv4 (kromě polí „adresa odesílatele“ a „cílová adresa“) bitovými poli, protože jejich velikost není 32 bitů a jejich adresy nejsou násobek 4 bajtů . Pokud navíc procesor podporuje přímé čtení a zápis 8bitových a 16bitových čísel, budou jedinými bitovými poli verze, velikost záhlaví, DSCP , ECN , příznaky a offset fragmentu.
Nechť jsou čtyři bitová pole v jednom bajtu:
Číslo bitu | 7 [*1] | 6 | 5 | čtyři | 3 | 2 | jeden | 0 [*2] |
---|---|---|---|---|---|---|---|---|
bitové pole | d | C | b | A | ||||
Hodnotu osmibitového čísla x , složeného z bitových polí a , b , cad , lze vypočítat pomocí vzorce: (1) .
Pokud a=1 , b=0 , c=2= 102 a d=5= 01012 , x bude .
Pokud procesor pracuje s binárními čísly, lze vzorec (1) optimalizovat . Po nahrazení operací " umocňování " za " logický posun ", " sčítání " za " bit OR " bude mít vzorec (1) tvar:
x = ( d << 4 ) | ( c << 2 ) | ( b << 1 ) | ALogický posun binárního čísla je ekvivalentní násobení/dělení násobkem mocniny dvou: 2 1 =2, 2 2 =4, 2 3 =8 atd.
Existují dva způsoby , jak získat hodnotu v nějakého bitového pole čísla x :
První metoda nejprve provede bitovou operaci AND a poté logický posun doprava. U druhého způsobu se operace provádějí v obráceném pořadí. Konstantu mask_2 lze získat z konstanty mask_1 : . offset je číslo prvního nejméně významného bitu bitového pole v , exponent ve vzorci (1) .
mask_2 = mask_1 >> offset
Chcete-li získat hodnotu bitového pole z čísla x prvním způsobem, provedou se tři operace:
Číslo bitu | 7 | 6 | 5 | čtyři | 3 | 2 | jeden | 0 |
---|---|---|---|---|---|---|---|---|
maska pro a | 0 | 0 | 0 | 0 | 0 | 0 | 0 | jeden |
maska pro b | 0 | 0 | 0 | 0 | 0 | 0 | jeden | 0 |
maska pro c | 0 | 0 | 0 | 0 | jeden | jeden | 0 | 0 |
maska pro d | jeden | jeden | jeden | jeden | 0 | 0 | 0 | 0 |
bitové pole | offset |
---|---|
A | 0 |
b | jeden |
C | 2 |
d | čtyři |
Příklad získání hodnoty z bitového pole c :
c = ( x & 00001100 b ) >> 2S druhým způsobem:
Číslo bitu | 7 | 6 | 5 | čtyři | 3 | 2 | jeden | 0 |
---|---|---|---|---|---|---|---|---|
maska pro a | 0 | 0 | 0 | 0 | 0 | 0 | 0 | jeden |
maska pro b | 0 | 0 | 0 | 0 | 0 | 0 | 0 | jeden |
maska pro c | 0 | 0 | 0 | 0 | 0 | 0 | jeden | jeden |
maska pro d | 0 | 0 | 0 | 0 | jeden | jeden | jeden | jeden |
Příklad získání hodnoty z bitového pole c :
c = ( x >> 2 ) & 00000011 bNejméně významné bitové pole ( v tomto příkladu pole a ) není logicky posunuto o nula bitů. Příklad:
a = ( x & 00000001b ) >> 0
a = ( x >> 0 ) & 00000001b )
Ve druhé metodě nejvyšší pole ( v tomto příkladu pole d ) neprovádí logické násobení, protože operace logického posunu doprava přidává k číslu nulové bity. Příklad:
d = ( x >> 4 ) & 00001111b )
Chcete-li nahradit bitové pole, provedou se tři operace:
Příklad nahrazení hodnoty za bitové pole d :
xnew = ( x & 00001111 b ) | ( d << 4 )Existují jednodušší metody pro práci s bitovými poli, která jsou jeden bit široká.
Pole bitů a a b zabírají každé po jednom bitu.
Pro získání hodnoty jednoho bitu se logické násobení (operace „ bit AND “) čísla x provede maskou, která má nastaven jeden bit, což odpovídá bitu jednobitového pole. Pokud je výsledek 0, bit je 0.
Příklad získání hodnoty jednobitového pole b :
b = ( ( x & 00000010 b ) != 0 )Pro kontrolu, zda je jeden nebo více bitů ze skupiny roven jedné, se vezme maska, ve které jsou jednotky nastaveny na pozice kontrolovaných bitů:
a_or_b = ( ( x & 00000011 b ) != 0 )Chcete-li zkontrolovat, zda jsou všechny bity ze skupiny rovny jedné, použijte „ bitový AND “ a operaci „ == “ :
a_and_b = ( ( x & 00000011 b ) == 00000011 b )Pro nastavení bitů se provede logické sčítání (operace " bit OR ") čísla x s maskou, která má jedničky nastavené na pozicích odpovídajících bitovému poli.
Příklad nastavení bitu jednobitového pole a :
x1 = x | 00000001b _Chcete-li nastavit několik bitů čísla x , například bity jednobitových polí a a b , použijte masku, která má bity odpovídající bitům bitových polí nastaveny na jedničky:
x2 = x | 00000011b _Pro nastavení jednoho nebo více bitů nul se číslo x vynásobí operací „ bit AND “ maskou, ve které jsou nulové bity nastaveny na pozice odpovídající bitovému poli.
Příklad nastavení bitů na nulu v bitovém poli b :
x3 = x & 11111101 bPro změnu hodnoty bitů na opačnou (z 0 na 1 a z 1 na 0) je číslo x přidáno operací „ bit exclusive OR “ s maskou, ve které jsou jednotky nastaveny na pozice odpovídající pozicím přepínací bity.
Příklad změny bitových hodnot bitového pole b :
x4 = x ^ 00000010b _V paměti počítače lze záporná celá čísla zakódovat jedním z následujících způsobů:
Většina moderních procesorů implementuje třetí metodu. Zvažte binární reprezentaci více celých čísel ve dvou doplňcích :
4 = 00000100 2 3 = 00000011 2 2 = 00000010 2 1 = 00000001 2 0 = 00000000 2 -1 = 11111111 2 -2 = 10000010 = 10 123 -111 10 atd.Nechť pole c a d mají formát " doplňkový kód ". Pak pole c může ukládat čísla od −2=10 2 do 1=01 2 a pole d může ukládat čísla od −8=1000 2 do 7=0111 2 .
Každý z členů (kromě nejvyššího), aby nekazil vyšší bity, je nutné vynásobit bitovou maskou příslušné délky. Zejména:
x = (d << 4) + ((c & 00000011b) << 2) + (b << 1) + aChcete-li získat čísla, musíte posunout pole o požadovaný počet bitů doprava a současně vynásobit bit znaménka. Můžete k tomu například použít aritmetický posun . Pokud je x dlouhé 8 bitů, pak
c = (x << 4 ) >>a 6 d = x >>a 4Pozornost! V programovacím jazyce Java je tomu naopak: znaménko značí aritmetický posun a znaménko logický posun . >>>>>
Pokud nedojde k aritmetickému posunu, pak...
c1 = x >> 2 if (c1 & 00000010b ≠ 0) pak c = c1 | 0x11111100b jinak c = c1 & 0x00000011bV C a C++ se při deklaraci bitového pole používá znak dvojtečky ( :) . Za dvojtečkou následuje konstantní výraz , který určuje počet bitů v bitovém poli [1] . Příklad:
struct rgb { nesignováno r : 3 ; nesignováno g : 3 ; nesignováno b : 3 ; };