123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- #include <stdio.h>
- unsigned getbits(unsigned x, int p, int n);
- unsigned int setbits(unsigned int x,unsigned int p,unsigned int n,unsigned int y);
- #define MAGIC_NUMBER 33091
- void shotgunPrintUint(const char name[], unsigned int in);
- unsigned int invertBits(unsigned int x,unsigned int p,unsigned int n);
- unsigned getInvertBits(unsigned x, int p, int n);
- int main()
- {
-
- shotgunPrintUint("return ",invertBits(0xdeadbeef,0,32));
- // printf("i:%u \t temp:%x \n",-1,temp);
- /** shifting 32 bits out is an overflow condition .*/
- // unsigned int temp = ~0;
- // unsigned int temp2=temp<<32;
- // printf("\t temp:%x \n",temp2);
- return(0);
- }
- /**
- a function invert(x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the others unchanged.
- */
- unsigned int invertBits(unsigned int x,unsigned int p,unsigned int n)
- {
- //printf(" x : %0#10x : p %d : n %d \n",x,p,n);
- unsigned int left = getbits(x,p+n,32-(n+p)); //if position is zero...we just want middle case to handle it.
- //shotgunPrintUint("left ",left);
-
- unsigned int left_out = ((n+p)<32) ? left << (n+p) :0 ;
- //left is in the right spot
- shotgunPrintUint("left_out",left_out);
-
- unsigned int middle = getInvertBits(x,p,n); //just like setbits only this part is inverted here.
- //shotgunPrintUint("middle ",middle);
- unsigned int middle_out = middle << p ;
- //shotgunPrintUint("middle_out",middle_out);
- shotgunPrintUint("middle_out",middle_out);
-
- unsigned int right_out = getbits(x,0,p); // | getbits(y,p,n);
- //shotgunPrintUint("right_out ",right_out);
-
- //printf(" right : %x \n ",right);
- // unsigned int right_out = right >> (n+p);
- shotgunPrintUint("right_out",right_out);
- return left_out | middle_out | right_out;
- }
-
- unsigned int setbits(unsigned int x,unsigned int p,unsigned int n,unsigned int y)
- {
- //printf(" x : %0#10x : p %d : n %d \n",x,p,n);
- unsigned int left = getbits(x,p+n,32-(n+p)); //if position is zero...we just want middle case to handle it.
- //shotgunPrintUint("left ",left);
-
- unsigned int left_out = ((n+p)<32) ? left << (n+p) :0 ;
- //left is in the right spot
- //shotgunPrintUint("left_out",left_out);
-
- unsigned int middle = getbits(y,p,n);
- //shotgunPrintUint("middle ",middle);
- unsigned int middle_out = middle << p ;
- //shotgunPrintUint("middle_out",middle_out);
- //shotgunPrintUint("middle_out",middle_out);
-
- unsigned int right_out = getbits(x,0,p); // | getbits(y,p,n);
- //shotgunPrintUint("right_out ",right_out);
-
- //printf(" right : %x \n ",right);
- // unsigned int right_out = right >> (n+p);
- //shotgunPrintUint("right_out",right_out);
- return left_out | middle_out | right_out;
- }
- /* the problem here is this function is in fact broken due to ~0 << n not
- being valid C anymore.
- KNR Bullshit: ~0 << n is not defined in ANSI C
- KNR getbits: get n bits from position p
- */
- /*
- even if it is in K&R C
- */
- /* getbits: get n bits from position p */
- unsigned getbits(unsigned x, int p, int n)
- {
- // shotgunPrintUint("test me",0x1);
- // shotgunPrintUint("test me",0x0);
- //printf ("getbits x: %0#10x ,p: %d ,n: %d \n",x,p,n);
- unsigned int leftmask,rightmask;
- leftmask = rightmask = ~0;
- //shotgunPrintUint("maxmask ",leftmask);
- leftmask = leftmask << p; //find position p
- // shotgunPrintUint("leftmask ",leftmask);
- int shiftme = 32-(p+n);
-
- rightmask = (shiftme < 32) ? rightmask >> shiftme : 0; //find position p
- //shotgunPrintUint("rightmask ",rightmask);
- //shotgunPrintUint("shiftme ",shiftme);
- unsigned int finalmask = leftmask & rightmask;
-
- unsigned int data = x & finalmask;
- shotgunPrintUint("mask ",finalmask);
- // shotgunPrintUint("data",data);
- unsigned int outdata = data >> p;
- //shotgunPrintUint("outdata",outdata);
-
- //unsigned int outdata = (x >> (p-n));
- // printf(" mask : %x \n ",mask);
- //shotgunPrintUint("outdata",outdata);
- return outdata; // (x >> (p-n)) & mask;
- }
- /**
- retrieve n bits starting position p from x, with the bits themselves inverted.
- */
- unsigned getInvertBits(unsigned x, int p, int n)
- {
- // shotgunPrintUint("test me",0x1);
- // shotgunPrintUint("test me",0x0);
- //printf ("getbits x: %0#10x ,p: %d ,n: %d \n",x,p,n);
-
- unsigned int leftmask,rightmask;
- leftmask = rightmask = ~0;
- //shotgunPrintUint("maxmask ",leftmask);
- leftmask = leftmask << p; //find position p
- // shotgunPrintUint("leftmask ",leftmask);
- int shiftme = 32-(p+n);
-
- rightmask = (shiftme < 32) ? rightmask >> shiftme : 0; //find position p
- //shotgunPrintUint("rightmask ",rightmask);
- //shotgunPrintUint("shiftme ",shiftme);
- unsigned int finalmask = leftmask & rightmask;
-
- unsigned int data = (~x) & finalmask;
- shotgunPrintUint("mask ",finalmask);
- // shotgunPrintUint("data",data);
- unsigned int outdata = data >> p;
- //shotgunPrintUint("outdata",outdata);
-
- //unsigned int outdata = (x >> (p-n));
- // printf(" mask : %x \n ",mask);
- //shotgunPrintUint("outdata",outdata);
- return outdata; // (x >> (p-n)) & mask;
- }
- /**
- caution if you printf, padded with 0's, a hex number of exactly 0 it will print
- as 0000000000 not 0x00000000
- */
- /**
- drop me in if you don't want to use a debugger like GDB to shotgun-debug
- print the value of a uint
- */
- void shotgunPrintUint(const char name[], unsigned int in)
- {
- printf(name,23423);
- printf("\t\t: %0#10x \n",in);
- return;
- }
|