Bit Wise
Bit Wise
Relevance to 'C' of bitwise applications Syntax and expressions Example getter and setter functions Eratothene's prime number sieve
'C' was designed to write system software as an alternative to assembler: compilers, kernels, 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
Different microprocessors organise integer and floating point data differently, e.g. big endian or little endian, two's or one's complement, location and size of exponent, sign bit and mantissa. Device drivers for different hardware implement different instruction sets.
Operator Summary
In-place operators
Inplace versions of operators exist which modify the LHS 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 . These work in the same manner as += , = and *= inplace operators compared to + and * .
The >> operator shifts a variable to the right and the << operator shifts a variable to the left. Zeros are shifted into vacated bits, but with signed data types, what happens with sign bits is platform dependant. The number of bit positions these operators shift the value on their left is specified on the right of the operator. Uses include fast multiplication or division of integers by integer powers of 2, e.g. 2,4,8,16 etc.
#include <stdio.h> int main(void){ unsigned int a=16; printf("%d\t",a>>3); /* prints 16 divided by 8 */ printf("%d\n",a<<3); /* prints 16 multiplied by 8 */ return 0; } output: 2 128
Single & and | operators (bitwise AND and OR) work differently from logical AND and OR ( && and || ). You can think of the logical operators as returning a single 1 for true, and 0 for false. The purpose of the & and | bitwise operators is to return a resulting set of output 1s and 0s based on the boolean AND or OR operations between corresponding bits of the input.
Symbol: ^ For each bit of output, this output is a 1 if corresponding bits of input are different, and the output is a 0 if the input bits are the same.
Symbol: ~ This is a unary operator in the sense that it works on a single input value. The bit pattern output is the opposite of the bit pattern input with input 1s becoming output 0s and input 0s becoming output 1s.
Prototype used:
void setbitn(unsigned char *cp, int bitpos, int value); /* setbitn sets bit position 0 7 of cp to 0 or 1 */
To return the value of a particular bit within a byte without changing the original, the following prototype was used:
int getbitn(unsigned char c, int bitpos); /* getbitn gets bit position 0 7 of c, returns 0 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.
void setbit(unsigned char *sp, size_t bitpos, int value); /* setbit sets bit position 0 ((MAXBYTES * 8) 1) to value 0 or 1 */ int getbit(unsigned char *sp, size_t bitpos); /* getbit gets bit position 0 ((MAXBYTES * 8) 1), returns 0 or 1 */
Parameter sp is passed the address of the array storing the bits, e.g. bitarray.
setbit function
void setbit(unsigned char *sp, size_t bitpos, int value){ /* setbit sets bit position 0 ((MAXBYTES * 8) 1) of string sp * to value 0 or 1 */ size_t byteno; int bit07; /* will store a value from 0 7 indicating bit in byte */ byteno=bitpos/8; /* floor division to get byte number in string */ if(byteno >= MAXBYTES){ fprintf(stderr,"setbit: buffer overflow trapped\n"); exit(1); /* needs #include <stdlib.h> */ } bit07=(int)bitpos%8; /* remainder value 0 7 */ setbitn(sp+byteno,bit07,value); }
getbit function
int getbit(unsigned char *sp, size_t bitpos){ /* getbit gets bit position 0 ((MAXBYTES * 8) 1) of sp, * returns 0 or 1 */ size_t byteno; int bit07; byteno=bitpos/8; /* floor division to get byte number in string */ if(byteno >= MAXBYTES){ fprintf(stderr,"getbit: read beyond end of buffer \n"); fprintf(stderr,"bitpos: %d\n",bitpos); exit(1); } bit07=(int)bitpos%8; /* remainder value 0 7 */ return getbitn(*(sp+byteno),bit07); }
The sieve of Atkin is a faster version of Eratothene's sieve http://en.wikipedia.org/wiki/Sieve_of_Atkin Small primes can be used to test whether a random number is a much larger prime using the Rabin Miller primality test. http://en.wikipedia.org/wiki/Primality_test