C Programming - Bitwise Operations

Hello, I am trying to write a C program that uses 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. I am almost sure that I have the return function x in setbits() is correct. since I got the first output correct. I am confused on why my other three outputs are incorrect, can someone please tell me why or modify my code / setbits() function to get the Desired Output?

Desired Output:
setbits(x=0x1234, p=15, n=8, y=0xffff) => 0xff34
setbits(x=0x1234, p=14, n=3, y=0x2) => 0x2234
setbits(x=0x1234, p=20, n=6, y=0xf2) => 0x191234
setbits(x=0x1234, p=31, n=4, y=0x192f) => 0xf0001234

Actual Output:
setbits(x=0x1234, p=15, n=8, y=0xffff) => 0xff34
setbits(x=0x1234, p=14, n=3, y=0x2) => 0x234
setbits(x=0x1234, p=20, n=6, y=0xf2) => 0x1234
setbits(x=0x1234, p=31, n=4, y=0x192f) => 0x1234

The C Code I have is below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 #include <stdio.h>

unsigned setbits(unsigned x,int p,int n,unsigned y);

int main()
{
	int x,p,n,y;

  printf("setbits(x=0x%x, p=%d, n=%d, y=0x%x) => 0x%x\n",
     0x1234, 15, 8, 0xffff, setbits(0x1234, 15, 8, 0xffff));
  printf("setbits(x=0x%x, p=%d, n=%d, y=0x%x) => 0x%x\n",
     0x1234, 14, 3, 2, setbits(0x1234, 14, 3, 2));
  printf("setbits(x=0x%x, p=%d, n=%d, y=0x%x) => 0x%x\n",
     0x1234, 20, 6, 0xf2, setbits(0x1234, 20, 6, 0xf2));
  printf("setbits(x=0x%x, p=%d, n=%d, y=0x%x) => 0x%x\n",
     0x1234, 31, 4, 0x192f, setbits(0x1234, 31, 4, 0x192f));
}

unsigned setbits(unsigned x,int p,int n,unsigned y)
{
	return x & ~(~(~0 << n) << (p+1-n)) | ( y & (~(~0<<n)) << (p+1-n));
}
Extra tricky code makes extra tricky errors. Break it down.

You need two masks, one for the N bits starting at xp, and one for the N LSB bits of y.

It is also useful to put that shift expression as a variable.

Also, I added a test case.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>

unsigned setbits(unsigned x,int p,int n,unsigned y);

int main()
{
//	int x,p,n,y;

  printf("setbits(x=0x%x, p=%d, n=%d, y=0x%x) => 0x%x\n",
     0x1234, 15, 8, 0xffff, setbits(0x1234, 15, 8, 0xffff));
  printf("setbits(x=0x%x, p=%d, n=%d, y=0x%x) => 0x%x\n",
     0x1234, 14, 3, 2, setbits(0x1234, 14, 3, 2));
  printf("setbits(x=0x%x, p=%d, n=%d, y=0x%x) => 0x%x\n",
     0x1234, 20, 6, 0xf2, setbits(0x1234, 20, 6, 0xf2));
  printf("setbits(x=0x%04x, p=%d, n=%d, y=0x%04x) => 0x%04x\n",
     0x1234, 31, 4, 0x192f, setbits(0x1234, 31, 4, 0x192f));
  printf("setbits(x=0x%X, p=%d, n=%d, y=0x%X) => 0x%04X\n",
     0x1234, 8, 4, 0xE, setbits(0x1234, 8, 4, 0xE)); // 13D4
}

unsigned setbits(unsigned x,int p,int n,unsigned y)
{
//	return x & ~(~(~0 << n) << (p+1-n)) | ( y & (~(~0<<n)) << (p+1-n));
  int      shift = p - n + 1;
  unsigned mask  = (1U << n) - 1;
  return (x & ~(mask << shift)) | ((y & mask) << shift);
}

Which produces the correct output:
setbits(x=0x1234, p=15, n=8, y=0xffff) => 0xff34
setbits(x=0x1234, p=14, n=3, y=0x2) => 0x2234
setbits(x=0x1234, p=20, n=6, y=0xf2) => 0x191234
setbits(x=0x1234, p=31, n=4, y=0x192f) => 0xf0001234
setbits(x=0x1234, p=8, n=4, y=0xE) => 0x13D4


[edit]
What happens if bad values of p and n are supplied?
[/edit]

Hope this helps.
Last edited on
Topic archived. No new replies allowed.