#include <stdio.h>

/**
 * Exercise 2-6.  Write a function setbits(x,p,n,y) that returns 
 * x with the n bits that begin at position p set to the rightmost 
 * n bits of y, leaving the other bits unchanged.
 */

void displaybits(unsigned,int);
unsigned getbits(unsigned,int,int);
unsigned setbits(unsigned,int,int,unsigned);

void displaybits(unsigned x, int numbits)
{
   int i;
   for(i=numbits-1; i>=0; i--)
      printf("%d",(x&(1<<i))>0 ? 1 : 0);
   printf("\n");
}

unsigned getbits(unsigned x, int p, int n)
{
   return (x >> (p+1-n)) & ~(~0 << n);
}

unsigned setbits(unsigned x, int p, int n, unsigned y)
{
   int changedbits = getbits(y,n-1,n);     /* Get the rightmost n bits of y   */
   int xbits_upper  = getbits(x,31,31-p);  /* Get upper (unchanged) bits in x */
   int xbits_lower = getbits(x,p-n,p+1-n); /* Get lower (unchanged) bits in x  */
   return (xbits_upper << p+1) | (changedbits << (p+1-n)) | xbits_lower;
}

/* Alternatively, you can write the function below.  However, this function 
is not only difficult to read but is also difficult to reuse.  The setbits 
function above can be easily adapted to change the bits to some other 
calculate bitstream. 
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
   return 
   ((((x >> (p+1-n)) & (~0 << n)) | 
   (y & ~(~0 << n))) << (p+1-n))  | 
   (x & ~(~0 << (p+1-n)));
}
*/

int main(void)
{
   unsigned x = 128482;
   displaybits(x,32);
   displaybits(setbits(x,8,4,0),32);
   return 0;
}
