Portál AbcLinuxu, 24. dubna 2024 19:28


Dotaz: Bitové operace, bitová pole C

20.9.2011 18:12 novacek
Bitové operace, bitová pole C
Přečteno: 2446×
Odpovědět | Admin
Ahoj, učím se jazyk C z knihy od K&R a ve druhé kapitole je podkapitolka s názvem bitové operátory. Moc to nechápu, sice převádět decimální hodnotu do binární soustavy umím, ale to teď nebude zrovna vše. Neexistuje nějaký návod, článek či publikace pro úplné začátečníky v tomto smyslu? Děkuji všem.

ps: googlil jsem, bohužel tam byly jen návody pro |,&, atd... to mi je teď celkem naprd, když absolutně nevím, k čemu se to dělá a jak...doufám, že mě chápete :/

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

20.9.2011 18:41 Magog | skóre: 6
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Odpovědět | | Sbalit | Link | Blokovat | Admin
Docela dobře je to napsáno tady: http://cs.wikipedia.org/wiki/Bitov%C3%BD_oper%C3%A1tor

Jinak je vhodné vědět, že v paměti je uloženo číslo ve dvojkové soustavě. Takže tyhle operátory jsou velice rychlé, například pro zjišťování, zda je číslo liché nebo sudé.
20.9.2011 20:15 novacek
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Jo, tohle bych i chápal, jen mi vrtá hlavou, k čemu to vlastně je (když se to dá zjistit např. vydělením 2ma).. a jak se např. zjistí, kde v paměti je daný bit vůbec uložen... omlouvám se, jestli vám přijde tahle otázka stupidní, bohužel, pro mě, jakožto začátečníka, dosti zásadní :(

ps: když bych chtěl sečíst hodnotu znaku A + hodnotu znaku B, tak to musím nejprve převést do binární soustavy a až teprve aplikovat OR ?
20.9.2011 20:52 l4m4
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Uložení: každý bajt má osm bitů, int má běžně 32, a takhle přesně vypadají v paměti, jako skupiny bitů. Všechna běžná záznamová zařízení ukládají všechno po bitech. Nic se do binární soustavy nepřevádí, ono to v ní celou dobu je. To, že píšeš něco decimálně, hexadecimálně nebo jak, je proto, aby ses nezbláznil, ale je to prostě jen zápis, reálně jsou to pořád skupiny bitů.

Sečtení: Hodnoty dvou znaků A a B se sečtou tak, že se sečtou ty hodnoty těch dvou znaků A a B. Můžeš ty hodnoty a výsledek zapsat decimálně, binárně, ternárně nebo jak chceš, ale součet je prostě součet, na zápisu nezáleží.
20.9.2011 21:03 Magog | skóre: 6
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Konkrétně třeba určení lichosti/sudosti čísla znamená nahlédnout na poslední bit - když je 0, je číslo sudé, jinak je liché. Tedy vlastně vyhodnocuji cislo & 1 == 1. Při dělení celého čísla celým číslem, dostanu opět celé číslo se zahozeným zbytkem (např. 26/10=2). Budu-li chtít zjistit sudost čísla pomocí dělení, musím vydělit číslo dvojkou, pak vynásobit dvojkou a porovnat s původním číslem, jestli jsem dostal to samé. Což znamená výrazně vyšší časovou složitost.

Moc pěkné využití bitových operátorů je pro masky. Představte si, že máte nějaký systém, do kterého přistupuje více lidí. Těmto lidem chceme udělovat nějaká oprávnění. Daný člověk oprávnění buďto má, nebo nemá. Žádná jiná možnost není přípustná. Tato oprávnění seřadím v libovolném pořadí. Teď už mi stačí udělat jen to, že každému uživateli přiřadím jedno číslo ve dvojkové soustavě, které bude reprezentovat jeho množinu oprávnění. Na dané pozici bude 1, pokud oprávnění má, a 0, pokud ne. Zjišťování a nastavování oprávnění lze jednoduše implementovat pomocí binárních operátorů při velice nízké spotřebě procesorového času i paměti.

Máte-li dvě proměnné typu char, můžete na ně bez problémů použít OR. Následující kód tedy bude fungovat bez problémů:
char a = 'A';
char b = 'B';
char c = a | b;
21.9.2011 16:24 novacek
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Děkuji moc za váš příspěvek, začínám to chápat a hlavně musím uznat, že cislo & 1 == 1 je geniální a uspoří to i pár řádků, nejen výkon procesoru. Ještě taková poznámečka, jestli není dost stupidní, ale dá se nějak vypsat hodnota např 'A' + 'B' v binární soustavě pomocí funkce printf ? (vím, že to vůbec nebudu potřebovat a vy asi taky ne, ale existujě něco takového?). Díky
21.9.2011 17:49 l4m4
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Pomocí printf() nedá, nicméně printf() umí vypisovat šestnáctkově (%x) a osmičkově (%o), což je s trochou cviku snadno čitelné jako binární čísla, protože na každá cifra odpovídá skupině čtyř resp. tří bitů, navíc je to stručnější.
22.9.2011 15:35 novacek
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Díky za hodnotnou diskuzi. Tímto příspěvkem bych chtěl tohle uzavřít a všem poděkovat, zejména 2 pánům, kteří mi to od základů vysvětlili. Snad budu někdy dobrý jako vy. Díky všem!
AraxoN avatar 20.9.2011 21:14 AraxoN | skóre: 47 | blog: slon_v_porcelane | Košice
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Naposledy keď som sa o to zaujímal, tak som došiel k tomu, že inštrukcia celočíselného delenia na bežnom x86 trvá desiatky až stovky taktov procesora. Naopak, inštrukcia bitového súčtu sa vykoná za jeden-dva takty. To sa môže líšiť procesor od procesora, presnejšie by to bolo treba pozrieť v aktuálnej špecifikácii. Keď ale potrebuješ zistiť deliteľnosť dvojkou, tak použiť delenie je čistý nerozum. Iba ak by si chcel, aby táto časť programu išla stokrát pomalšie...
20.9.2011 22:20 l4m4
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
A jak jsi k tomu došel? Ani 128bitový DIV netrvá stovky taktů (i když ke stovce se to při děliteli, který je skutečně více než 64bitový, může blížit).

Zjištění dělitelnosti 2 pomocí operátoru % inteligentní kompilátor na bitovou operaci zoptimalizuje a za normálních okolností se tím nikdo nemusí zabývat.

A pochybuji, že toto celé nějak pomůže člověku, který má zjevně jen matnou představu, co je to bit...
AraxoN avatar 21.9.2011 00:04 AraxoN | skóre: 47 | blog: slon_v_porcelane | Košice
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Asi som mal dodať, že naposledy keď som sa o to zaujímal, tak Intel Pentium 120MHz bol moderný procesor. Z toho, čo som teraz narýchlo vygooglil, tak u 486 to sú desiatky taktov. Pre novšie procesory som takéto tabuľky už nenašiel. Rád sa nechám poučiť.
21.9.2011 17:52 l4m4
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
U novějších procesorů je doba vykonávání variabilní a závisí na skutečné velikosti operandů, tj. procesor je dost chytrý, aby 128bitové dělení, kde je dělitel reálně jednobajtový (všechny vyšší bity nuly), nepočítal jako plné 128bitové dělení. Nejdelší doba je na Intelu IIRC asi 90 taktů.
29.4.2013 22:10 Martin
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Nedávno jsem zkoumal efektivitu celočíselného násobení versus bitový posun na tomto příkladu: return a*5; versus return (a<<2)+a; a při kompilaci GCC už při optimalizaci -O1 z obou zápisů vygeneroval naprosto shodný assembler. Takže myslím, že u toho dělení to bude stejně tak a programátor se nemusí o optimalizaci na této úrovni starat, neboť to za něj udělá překladač.
20.9.2011 19:51 l4m4
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Odpovědět | | Sbalit | Link | Blokovat | Admin
Doufám, že je to aspoň second edition, která vyšla zhruba současně s ANSI C standardem v roce 1988 (a je tedy jen středně zastaralá). První vydání popisující původní K&R C, které nemá ani protoypy funkcí, je zajímavé především historicky...
20.9.2011 20:06 novacek
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Ano, druhé vydání, jsou tam i komentáře od velkého miroslava viriuse k C99
20.9.2011 23:57 Sten
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Odpovědět | | Sbalit | Link | Blokovat | Admin
Používání bitových operací pro počítání (násobení, dělení) je s dnešními překladači úplně na houby, akorát si tím znepřehledníte kód. Překladače to totiž udělají za vás. Jediné, k čemu se stále hodí, jsou vlaječky (flagy), též zvané bitové masky. Třeba veškerá práva pro soubor lze uložit do jednoho bajty, kde jednotlivé bity představují jednotlivá práva. Potom můžeme definovat vlaječky představující práva třeba takto:
#define EXECUTE (1 << 0) // 0. bit
#define WRITE (1 << 1) // 1. bit
#define READ (1 << 2) // 2. bit
Taková práva lze potom snadno testovat právě pomocí binárních operací:
if (perm & EXECUTE) {
    // Lze spouštět
}

if (perm & (READ | WRITE)) {
  // Lze číst i zapisovat
}
Stejně tak je lze i měnit:
perm &= ~EXECUTE;
// Nyní je (perm & EXECUTE) vždy nepravdivé, tj. 0. bit je vždy 0
perm |= WRITE;
// Nyní je (perm & WRITE) vždy pravdivé, tj. 1. bit je vždy 1
21.9.2011 16:48 novacek
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
I vám děkuji za hodnotný příspěvěk, jen se chci zeptat, když posunu 1 bit doleva o 0 hodnot, jak jste to udělal vy se spustitelným souborem, dostanu tu samou hodnotu, čili 1, že? A když sečtu 1 0 + 1 0 0 dostanu 110, což je 6, tak se chci zeptat, jestli ta podmínka if funguje takhle : výsledek 0 bit - nepravda, výsledek 1 bit a více, v tomto případě 1 1 0 mi dá pravdu? Díky za objasnění. už se v tom začínám trochu orientovat.
21.9.2011 17:51 Sten
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Ano, posun o nula bitů nic neudělá a kompilátor takový posun odstraní. Ponechávám jej ale pro přehlednost.

Ano, prava je jakékoliv číslo s jinou hodnotou než 0.

Jinak jsem si všiml, že tam mám chybu:
if (perm & (READ | WRITE)) {
  // Špatně: Lze číst i zapisovat
  // Správně: Lze číst nebo zapisovat (nebo oboje)
}

if ((perm & READ) && (perm & WRITE)) {
  // Lze číst i zapisovat
  // "moderní" styl
  // Nemusí být bezpečné, pro masky pouze s jedním bitem!
}

if (perm & (READ | WRITE) == (READ | WRITE)) {
  // Lze číst i zapisovat
  // "klasický" styl
  // Bezpečné, i pro masky, které mohou mít více bitů (zde díky použití |)
  // Pokud má maska jenom jeden bit, kompilátor to porování stejně odstraní
}
22.9.2011 15:25 novacek
Rozbalit Rozbalit vše Re: Bitové operace, bitová pole C
Ok, díky mnohokrát.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.