1. ## [C] Setbits function

Hello, im reading The C Programming Language at the moment and i have come to a problem with bitwise operators.

Exercise:
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.

I understand what the function works. But i am sort of stuck when i try to put this into code. I really dont know how to start, and how should i think when approaching this problem? I know all the basic bitwise operators but i've never used them before in a program, specially not for solving problems.

This is all i could come up for now.

Code:
```#include <stdio.h>
#include <stdlib.h>

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

}

int main(int argc, char *argv[])
{

unsigned int a=0x01234567;

unsigned int b=0xFEDCBA98;

setbits(a, 30, 10, b);

//variable a should now be:          0101 0011 0000 0011 0100 0101 0110 0111
//                                   5     3     0    3    4    5    6    7

system("PAUSE");
return 0;
}```

2. Well for starters, unless they change their function's prototype/definition and how they call it, this can never hope to work.

Quzah.

3. Originally Posted by quzah
Well for starters, unless they change their function's prototype/definition and how they call it, this can never hope to work.

Quzah.
hmm? It's an exercise.

4. Yes, and typically in an exercises I see posted here, they provide a sample chunk of code (which is what always gets posted here, see: subsets filling the gaps question..) showing how they expect you to call it, etc. At any rate, since you're expected to return X, you should probably have your function return something. Oh, and you probably want to store that some place.

Quzah.

5. Perhaps something along these lines.
Code:
```Clear all bits from y except the rightmost n bits.
Left shift y's rightmost n bits locating them at p.
OR them together with the n bits from x located at p.```

6. Originally Posted by itCbitC
Perhaps something along these lines.
Code:
```Clear all bits from y except the rightmost n bits.
Left shift y's rightmost n bits locating them at p.
OR them together with the n bits from x located at p.```
Thanks, this helped alot .

I was thinking about something like this.

Code:
```unsigned int setbits(unsigned int a, int p, int n, unsigned int b)
{
b<<32-n;    //clearing all bits from b except the n rightmost by shifting them to the left side
b>>32-p-1; //moving bits in b to the right side (for needed positions) so their bit positions match for those in a

//since all bits in b except the n bits are 0, we can do a logical OR - a OR b

a | b;

return a;

}```
I think this is a rough estimation of what the function asks, but still not sure, may i get any feedback?

7. Originally Posted by Tool
Code:
```unsigned int setbits(unsigned int a, int p, int n, unsigned int b)
{
b<<32-n;    //clearing all bits from b except the n rightmost by shifting them to the left side
b>>32-p-1; //moving bits in b to the right side (for needed positions) so their bit positions match for those in a

//since all bits in b except the n bits are 0, we can do a logical OR - a OR b

a | b;

return a;

}```
I think this is a rough estimation of what the function asks, but still not sure, may i get any feedback?
Yep! that is exactly it.

8. ok, i tried a few examples but it appears to be a bit buggy.

My code always returns 1022, instead of 1023. I dont know whats the problem, maybe the position counter starts from 0 when it comes to counting how many spaces it shifts or?

Example:

setbits (1022, 2, 3, 407) = 1023

x --> 11 1111 1110 //it starts from the bolded position (including it)
y --> 01 1001 0111

so x becomes --> 11 1111 1111.

so here is my code. and theres something wrong with it because i keep geting 1022 instead of 1023. Perhaps it has something to do with shifting but i did try many combinations + - 1 or something like that.

Code:
```#include <stdio.h>
#include <stdlib.h>

unsigned int setbits(unsigned int a, int p, int n, unsigned int b)
{
b<<(32-n); //clearing all bits from b except the n rightmost by shifting them to the left side
b>>(32-p); //moving bits in b to the right side (for needed positions) so their bit positions match to those in a

//since all bits in b except the n bits are 0, we can do a logical OR - a OR b

a | b;

return a;

}

int main(int argc, char *argv[])
{

unsigned int a=1022;

unsigned int b=407;

unsigned int x=0;

x=setbits(a, 2, 3, b);

printf("%d", x);

system("PAUSE");
return 0;
}```

9. Either Save the value of the bitwise OR back into a (otherwise it is lost) or return the result of the operation w/o the need of saving.
Code:
```#include <stdio.h>

unsigned int setbits(unsigned int a, int p, int n, unsigned int b)
{
b<<(32-n);
b>>(32-p);
return a | b;
}

int main(int argc, char *argv[])
{
unsigned int a=1022;
unsigned int b=407;
unsigned int x=0;
x=setbits(a, 2, 3, b);
printf("%d", x);
system("PAUSE");
return 0;
}```

10. Maybe you mean to do
Code:
`b <<= (32 - n)`
... or at least some way to assign b. I haven't coded it to check the logic but just looking quickly I'd say you have to make sure you don't lose your results... like itCbitC said.

11. Don't assume that an integer will be 32 bits - it may not be on some systems. A portable calculation would be something like: sizeof( int ) * CHAR_BIT.

12. Notice though that the original problem is a bit ambiguous. There might be another wrinkle. What if one of the bits in b is 0? Does that mean the function should not set the bit (as the examples in this thread have done), or does it mean it should /clear/ that bit of a?

Anyway, the latter is very easy to implement as well. Just clear those bits in a that are going to be overwritten with bits from b.
Code:
```#include <limits.h>  /* for CHAR_BIT */

unsigned int setbits(unsigned int a, int p, int n, unsigned int b)
{
const unsigned int bits = sizeof(unsigned int) * CHAR_BIT;

unsigned int mask = (unsigned int)-1;  /* set mask to be all 1's */
/* now mask contains 1's where a's bits are to be replaced with b's bits */

b <<= bits - n;
b >>= bits - p;

a &= ~mask;  /* clear bits of a that are to be replaced by bits from b */
return a | b;
}```
Ah, there must be a better way. Let's see. You could assemble the resulting number piecewise.
Code:
```#include <stdio.h>
#include <limits.h>  /* for CHAR_BIT */

unsigned setbits(unsigned a, int p, int n, unsigned b)
{
const unsigned bits = sizeof(unsigned) * CHAR_BIT;
unsigned value = 0;

left_mask = (unsigned)-1 << (p + n);
right_mask = (unsigned)-1 >> (bits - p);

value |= (b << p) & ~left_mask;

return value;
}

int main() {
printf("%x\n", setbits(0xf0, 2, 3, -1u));
return 0;
}```
[Coloured with codeform.]

(Notice my leaving out of "int" in "unsigned int", because it's not necessary.)

Not sure if that's right, and I don't feel like testing it any further, but you get the idea even if it's wrong. I hope.

left_mask is 1's where the result should copy bits from a, left of the inserted bits from b. right_mask is 1's where the result should copy bits from a, right of bits from b.

13. >> right_mask = (unsigned)-1 >> (bits - p);

bits - p is just going to give you the number of bits that bounds 'n', not the remaining number of bits at the end. So basically a mask of ( ~0UL << p ) & ( ~0UL >> ( ( sizeof( unsigned ) * CHAR_BIT ) - ( p + n ) ) ) would give you the range of bits to be copied and the inverse of the mask would be the bits to preserve. AND these masks with the input values ('b' and 'a', respectively) and then OR the results together to get the final result.

EDIT: Nice syntax highlighting, BTW. Uh, do you mind if I borrow it?

14. Originally Posted by dwks
Notice though that the original problem is a bit ambiguous. There might be another wrinkle. What if one of the bits in b is 0? Does that mean the function should not set the bit (as the examples in this thread have done), or does it mean it should /clear/ that bit of a?
Whoa! good catch: "a zero bit in y OR'ed with a one bit in x won't set it to zero".
Originally Posted by dwks
Anyway, the latter is very easy to implement as well. Just clear those bits in a that are going to be overwritten with bits from b.
Yep! that too is easy and here's my 2c:
Code:
```#include <stdio.h>

int setbits(unsigned x, unsigned p, unsigned n, unsigned y)
{
unsigned l, r;
l = ~0 << (p+1);
r = (1 << p+1-n) - 1;
x &= (l | r);
y = (y & ~(~0 << n)) << p+1-n;
return x | y;
}

int main(int argc, char **argv)
{
printf("x:  %u\n", setbits(0xbce14e, 15, 3, 10));
}```
Not sure what you intended by the number in red below.
Originally Posted by dwks
Ah, there must be a better way. Let's see. You could assemble the resulting number piecewise.
Code:
`printf("%x\n", setbits(0xf0, 2, 3, -1u));`

15. Sorry, guys, I ran both of your functions and each returned the wrong results. For instance, setbits(85, 170, 1, 4) should output 75, but dwks' function returns 2147483733 and itCbitC's 85. If understand it correctly, it should work something like this:

Code:
```  01010101 ('a' = 85)
& 11100001 (preserve from 'a')
__________
01000001

10101010 ('b' = 170)
& 00011110 (copy from 'b')
__________
00001010

01000001
| 00001010
__________
01001011 (result = 75)```
Or am I missing something here?