Bitfield (C++)

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 6. října 2014; kontroly vyžadují 48 úprav .

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 .

O hardwarových implementacích

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:

0011 0100 1010 11 10 01 00 0111 0100 1100 2
  1. Procesor načte z paměti strojové slovo rovné původní hodnotě:
0011 0100 1010 11 10 01 00 0111 0100 1100 2
  1. Instrukce nastaví bity , and které nejsou v bitovém poli, na 0. Výsledek:
0000 0000 0000 00 10 01 00 0000 0000 0000 2
  1. Instrukce posune bity bitového pole zleva doprava tak, aby se nejméně významný bit bitového pole stal nejméně významným bitem strojového slova . Výsledek:shr
0000 0000 0000 0000 0000 0000 0000 1001 2

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:

0011 0100 1010 1110 0100 011 1 0100 1100 2 0011 01 00 1010 1110 0100 0111 0100 1100 2
  1. Procesor načte z paměti dvě strojová slova obsahující požadované bity; hodnoty se rovnají originálu:
0011 0100 1010 1110 0100 011 1 0100 1100 2 0011 01 00 1010 1110 0100 0111 0100 1100 2
  1. Pomocí dvou instrukcí and budou bity nezahrnuté v bitovém poli zapsány s hodnotami 0. Výsledek:
0000 0000 0000 0000 0000 000 1 0100 1100 2 0011 01 00 0000 0000 0000 0000 0000 0000 2
  1. S pomocí instrukce budou bity shrdruhého strojového slova posunuty zleva doprava tak, aby se nejméně významný bit bitového pole stal nejméně významným bitem strojového slova . Pomocí instrukce budou bity shlprvního strojového slova posunuty zprava doleva tak, aby byly pro bity druhého strojového slova (pro další krok) uvolněny nejméně významné bity. Výsledek:
0000 0000 0000 0000 0 101 0011 00 00 0000 2 0000 0000 0000 0000 0000 0000 00 00 1101 2
  1. Pomocí instrukce se budou or bity dvou strojových slov "překrývat" přes sebe. Výsledek:
0000 0000 0000 0000 0 101 0011 0000 1101 2

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í .

O kompilátorech

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.

Aplikace

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.

Operace na vícebitových polích

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
  1. 7. bit je nejvýznamnější bit.
  2. 0. bit je nejméně významný bit.

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 .

Sestavení jednoho čísla z bitových polí

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 ) | A

Logický 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.

Extrahování bitového pole

Existují dva způsoby , jak získat hodnotu v nějakého bitového pole čísla x :

  • v = ( x & mask_1 ) >> offset;
  • v = ( x >> offset ) & mask_2.

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:

  1. vypočítat "bitovou masku" mask_1  - číslo, které má jednotky v bitech odpovídajících bitovému poli a nuly ve zbývajících bitech;
Čí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
  1. vynásobte "bitovou masku" číslem pomocí operace " bit AND ";
  2. provést logický posun doprava o offsetové bity.
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 ) >> 2

S druhým způsobem:

  1. provést logický posun doprava;
  2. vypočítat "bitovou masku" mask_2  - číslo, ve kterém je prvních nejméně významných číslic nastaveno na jedničky a zbývající číslice jsou nuly; n  je počet číslic bitového pole;
Čí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
  1. vynásobte "bitovou masku" číslem pomocí operace " bit AND ".

Příklad získání hodnoty z bitového pole c :

c = ( x >> 2 ) & 00000011 b

Nejmé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 )

a = x & 00000001 b

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 )

d = x >> 4

Substituce bitového pole

Chcete-li nahradit bitové pole, provedou se tři operace:

  1. vypočítá se maska ​​- číslo, jehož bity odpovídající bitovému poli mají nuly;
  2. operace " bit AND " vynásobí číslo x maskou; operace provádí nastavení nul v bitech odpovídajících masce;
  3. operace " bit inclusive OR " slouží k sečtení výsledného součinu a čísla x posunutého o počet bitů odpovídajících posunu bitového pole od začátku slova.

Příklad nahrazení hodnoty za bitové pole d :

xnew = ( x & 00001111 b ) | ( d << 4 )

Operace s jednobitovými poli

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.

Kontrola jednoho 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 )

Nastavení taktů

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 _

Odstranění beatů

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 b

Beat Switching

Pro 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 _

Operace na podepsaných polích ve dvojkovém doplňku

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 .

Sestavení a nahrazení čísel

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) + a

Vytahování čísel

Chcete-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 4

Pozornost! 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 & 0x00000011b

Deklarace bitového pole

V 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 ; };

Viz také

Poznámky

  1. Ray Lishner. C++. Reference = C++ v kostce / kap. vyd. E. Strogonová. - Petrohrad. : Peter , 2003 . - S. 193. - 907 s. - 3500 výtisků.  - ISBN 5-94723-928-0 , BBC 32.973-018.1ya22, MDT 681.3.06(03).