Syntax and expressions Example getter and setter functions Eratothene's prime number sieve Relevance to 'C' of Bitwise Applications 'C' was designed to write system software as an alternative to assembler: compilers !ernels device drivers interpreters relational database engines virtual machines" So this language needs access to raw hardware and individual bit values" Coding designed for specific hardware design features will be non portable" Portability Constraints #ifferent microprocessors organise integer and floating point data differently e"g" big endian or little endian two's or one's complement location and si$e of exponent sign bit and mantissa" #evice drivers for different hardware implement different instruction sets" Operator Summary In-place operators %n&place versions of operators exist which modify the '(S operand in place rather than returning the result for a seperate assignment e"g" a ))* b performs a right shift of b bits directly on a " +hese wor! in the same manner as ,* &* and -* in&place operators compared to , & and - " Left and Right Shift Operators +he )) operator shifts a variable to the right and the .. operator shifts a variable to the left" /eros are shifted into vacated bits but with signed data types what happens with sign bits is platform dependant" +he number of bit positions these operators shift the value on their left is specified on the right of the operator" 0ses include fast multiplication or division of integers by integer powers of 1 e"g" 12345 etc" Left and right shift eample #include <stdio.h> int main(void){ unsigned int a=16; printf("d!t""a>>#); $% prints 16 divided &' ( %$ printf("d!n""a<<#); $% prints 16 multiplied &' ( %$ return ); * output: 1 413 Bitwise !"# and inclusi$e OR Single 6 and 7 operators 8bitwise A9# and :R; wor! differently from logical A9# and :R 8 66 and 77 ;" <ou can thin! of the logical operators as returning a single 4 for true and = for false" +he purpose of the 6 and 7 bitwise operators is to return a resulting set of output 4s and =s based on the boolean A9# or :R operations between corresponding bits of the input" Bitwise !"#%OR eample #include <stdio.h> int main(void){ unsigned char a=+!,))+"&=+!,ff+"c; c=+!,-)+ . +!,)/+; $% )1)1)))) . )))))111 %$ printf("he, -) . )/ is ,!n""c); c=+!,/#+ 0 +!,#/+; $% )111))11 0 ))11)111 %$ printf("he, /# 0 #/ is ,!n""c); return ); * :utput: hex >= 7 =? is >? hex ?@ 6 @? is @@ Bitwise eclusi$e OR operator Symbol: A Bor each bit of output this output is a 4 if corresponding bits of input are different and the output is a = if the input bits are the same" One's complement operator Symbol: C +his is a unary operator in the sense that it wor!s on a single input value" +he bit pattern output is the opposite of the bit pattern input & with input 4s becoming output =s and input =s becoming output 4s" Setting a particular bit within a byte Drototype used: void set&itn(unsigned char %cp" int &itpos" int value); $% set&itn sets &it position ) 1 / of cp to ) or 1 %$ +he byte cp 8assuming chars are 4 byte wide; is passed by reference" Setting a particular bit within a byte void set&itn(unsigned char %cp"int &itpos"int value){ $% set&itn sets &it position ) 1 / of cp to value ) or 1 %$ unsigned char template=(unsigned char)1; $% first ma2e template containing 3ust the &it to set %$ template<<=&itpos; if(value) $% true if value is 1 false for ). 4it5ise 67 sets templated &it in cp to 1 5hatever its current value" leave other &its unchanged %$ %cp=%cp . template; else $% 8nvert template 1s and )s. 9se &it5ise :;< to force templated &it in cp to ) % and leave all other &its in cp unchanged %$ %cp=%cp 0 ( = template); * &etting a particular bit within a byte +o return the value of a particular bit within a byte without changing the original the following prototype was used: int get&itn(unsigned char c" int &itpos); $% get&itn gets &it position ) 1 / of c" returns ) or 1 %$
Call by value is used for the byte concerned so this can be changed within the function but as this is a copy the original byte won't be changed" &etting a particular bit within a byte int get&itn(unsigned char c" int &itpos){ $%get&itn gets &it position ) 1 / of c" returns value ) or 1. >his function 5rites to c" &ut as 5e are using pass &' value" this 5on+t affect the original calling cop'. %$ unsigned char template=(unsigned char)1; $% ma2e template containing 3ust the &it to get %$ template<<=&itpos; c0=template; $% if relevant &it set then c is assigned non null" other5ise c is assigned null (all ?eros) %$ if(c) return 1; else return ); * Simulating a Boolean !rray 'C' doesn't have a Boolean type" Ee can store =s and 4s in chars or ints one bit per variable but this wastes space" +o access individual bits from a large memory&efficient set of bits we can use a char array to allocate the storage and then once we have identified the correct char 8byte; we can use our getbitn and setbitn functions to set and get individual bits" Ee can't use array notation for this but we can design accessor and mutator functions which can be called in a similar manner to array item read& ing and writing" 'et's define a constant: FAGB<+ES for the purpose of al& locating memory to our string array e"g" #define @:A4B>CD 1)))))) Ee can allocate the memory needed for the bit array: char &itarra'E@:A4B>CDF; +his gives storage of FAGB<+ES-3 bits and we can use the constant within the accessor and mutator functions to avoid a buffer overrun" getbit and setbit prototypes void set&it(unsigned char %sp" si?eGt &itpos" int value); $% set&it sets &it position ) 1 ((@:A4B>CD % () 1 1) to value ) or 1 %$ int get&it(unsigned char %sp" si?eGt &itpos); $% get&it gets &it position ) 1 ((@:A4B>CD % () 1 1)" returns ) or 1 %$ Darameter sp is passed the address of the array storing the bits e"g" bitarray" setbit function void set&it(unsigned char %sp" si?eGt &itpos" int value){ $% set&it sets &it position ) 1 ((@:A4B>CD % () 1 1) of string sp % to value ) or 1 %$ si?eGt &'teno; int &it)/; $% 5ill store a value from ) 1 / indicating &it in &'te %$ &'teno=&itpos$(; $% floor division to get &'te num&er in string %$ if(&'teno >= @:A4B>CD){ fprintf(stderr""set&itH &uffer overflo5 trapped!n"); e,it(1); $% needs #include <stdli&.h> %$ * &it)/=(int)&itpos(; $% remainder value ) 1 / %$ set&itn(spI&'teno"&it)/"value); * getbit function int get&it(unsigned char %sp" si?eGt &itpos){ $% get&it gets &it position ) 1 ((@:A4B>CD % () 1 1) of sp" % returns ) or 1 %$ si?eGt &'teno; int &it)/; &'teno=&itpos$(; $% floor division to get &'te num&er in string %$ if(&'teno >= @:A4B>CD){ fprintf(stderr""get&itH read &e'ond end of &uffer !n"); fprintf(stderr""&itposH d!n""&itpos); e,it(1); * &it)/=(int)&itpos(; $% remainder value ) 1 / %$ return get&itn(%(spI&'teno)"&it)/); * Eratothene's prime number sieve Eratothene's sieve is an algorithm we can use Huic!ly to obtain and store all small prime num& bers e"g" less than 1 @= "+o store these efficiently we need to use a bit array so that if the bit for the position in the array is a = the number for that pos& ition is prime and if the bit for this position is a 4 the number for that position is not prime" Ehen we have all the small prime numbers we can use these to test whether much larger randomly generated numbers are prime so they can be used for generating cryptographic !eys" Eratothene's prime number sieve Dositions in this array all start at = 8meaning the number or index of the position could be prime; except for positions = and 4 8which are not prime numbers" Starting with 1 this number is multiplied by 1 @ 2 etc" to stri!e out the even numbers starting 2 5 3 etc" up to the highest posi& tion in the boolean array" +hese bits are set to 4s mean& ing they can't be prime" +he next = in the array is then found which is the next prime number @ and this number is multiplied by all higher numbers and all multiples are set to 4" +his process continues until the first prime great& er than the sHuare root of the highest bit position is found" Bitwise operators are needed to implement Eratosthenes Sieve algorithm without wasting memory" 'ratothenes Sie$e main function int main(void){ $% from eratosthenes.c " 7ichard Ja'" Dept K))- %$ int i"3"ne,tprime=K"2; unsigned char aE@:A4B>CDF; $% allocate memor' for &it arra' %$ for(i=);i<@:A4B>CD;iII) aEiF=),)); $% initialise all &its to )s %$ set&it(a")"1); set&it(a"1"1); $% seed ) and 1 as not prime num&ers %$ printprime(K); 5hile(ne,tprimeI1<@:A4B>CD%(){ 2=ne,tprime; $% mar2 multiples of ne,tprime as not &eing possi&l' prime %$ 5hile(ne,tprime%2<@:A4B>CD%(){ set&it(a"ne,tprime%2"1); 2II; * $% find ne,tprime &' s2ipping non1prime &its mar2ed 1 %$ 5hile(ne,tprimeI1<@:A4B>CD%( 00 get&it(a"IIne,tprime)); printprime(ne,tprime); * return ); * 'ratothenes Sie$e printprime function void printprime(int prime){ $% prints a prime num&er in ne,t ( columns %$ static int numfound=); $% static so onl' initialises at compile time" and previous values are remem&ered in su&seLuent calls %$ if(numfound(==)) printf("!n"); $% start ne,t ro5 %$ if(primeI1<@:A4B>CD%() printf("d!t""prime); numfoundII; * >he a&ove program is Luite simple" &ut 5e didn+t need to store 5hether multiples of K 5ere prime or not. : minor improve1 ment to our data structure design 5ill halve the memor'. (urther reading on primes +he sieve of At!in is a faster version of Eratothene's sieve http:IIen"wi!ipedia"orgIwi!iISieveJofJAt!in Small primes can be used to test whether a random number is a much larger prime using the Rabin Filler primality test" http:IIen"wi!ipedia"orgIwi!iIDrimalityJtest