okay i understand all bitwise operators but in the chapter of k&r at bitwise operators i m really lost at there question i have no idea how to do them
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.
Exercise 2-7. Write 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.

3rd one was easy so i did it but i have no idea how to do those could anyone give me any idea how to code them ?

Recommended Answers

All 17 Replies

Well one of the ways for the first questions as I thought is this.

1> Take an input number n from the user.
2> "x" is an empty variable.
3> You have "y" as a number under concern.

What you need to do is pick the rightmost n bits of y and make a decimal number from it and feed it into x.
So you can do this.
* Assume an integer variable temp=1;
* Run a loop n-1 times and within it do
temp<<1;
temp | 1;
* After this loop you just need to do y & temp.
* The above algorithm will fetch you the right most n bits of y.

So your answer for 2-6 is x = y & temp;

In the same way try to answer 2-7. ;) The above code will make your other bits of "y" as 0. So you take another variable say z = y for your computations so that you ll get the results and also y will remain unchanged.

take the example: given x=0x55 (dec 85, binary 01010101), p=6, n=5, and y=0xEE (dec 238, binary 11101110)

what you want to happen is this:

x=  01010101  (0x55, dec 85)
p=6  ^        (bit #6)
n=5  .....    (get 5 bits)
    -10101--  (extracted from 'x'.  '-' are zeros)

y=  11101110  (0xEE, dec 238)
p=6  ^        (bit #6)
n=5  .....    (get 5 bits)
    -11011--  (extracted from 'y'.  '-' are zeros)

('r' return value is the value of 'x' with the
extracted bits replaced with the bits from 'y')

x=  0-----01  ('x', after extraction.  '-' are zeros)
    -11011--  (extracted from 'y'.  '-' are zeros)
+   ________
r=  01101101  (return value, 0x=6D, dec 109)

remember the function from your previous question

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

remember that the portion ~(~0 << n) created a bitmask of the form where number of 1's equaled the value of 'n' such that if n=5, a (16-bit) bit mask would be 0000000000011111 .

now this bitmask could be shifted two bits to the left, so that it looked like 0000000001111100 , and this could be used to extract the correct bits from 'y'

this same bitmask can then be inverted, so that it looked like 1111111110000011 , and this could be used to remove the no-longer-needed bits from x.

once youve removed the bits from 'x', its a simple matter to insert the corresponding bits that were extracted from 'y', by either adding or ORing.


.

but how can i assign those rightmost bits of y to rightmost of x ? is there somekind of specail loop i can go through to do that or i have to do it with bitwise operators?

also in the previous example of the K&R you specify the num you read in the bits but this example you have to get from n till like 0
lets say you said from number 5 in the bits you have to read till num 0 but in the other example of k&r you specify from 5 to 2 but how i know when it ends lets say you put num 5 how i know if i end at 1 or 0 or whatever..
i know i dont make much sense but this is rlly confusing me normally im good with normal coding....

why do a convoluted loop? the point, anyhow, is to learn bitwise operators. otherwise throw the chapter away and go learn about loops.

but i do see that i misunderstood part of the question. you're not being asked to extract 'n' bits of the 'y' value from the bit pointer 'p'. you're only need to extract the rightmost 'n' bits from 'y'

it's still essentially the same problem/solution as what i demonstrated. here is the same example:

given x=0x55, y=0xEE, p=6, n=5 .... remove the 'n=5' bits from 'x' starting at bit number 'p=6', and replace them with the rightmost 'n=5' bits from 'y' ... you've already got the components that you need from the previous example ~(~0 << n) creates a bitmask of size 'n', and x << (p+1-n) will left-shift (notice i changed direction) the number of bits that you need based on 'p' and 'n'

in the example p=6, n=5, you want a mask starting at bit #6 and to be 5 bits wide, so the last bit must be bit #2 (bit #'s 6,5,4,3,2 = 5 bits total) and therefore you will left-shift the bitmask 2 bits. hence, p+1-n = 2.

so create a bitmask 5 bits wide 0000000000011111 , and AND it with 'y' to extract the rightmost 5 bits of 'y' into a new variable, say "y1".

shift "y1" two places to the left using the code you should now understand, shown above.

shift teh bitmask 2 bits to the left using the same code, so the bitmask now looks like 0000000001111100 , then invert the bitmask so it becomes 1111111110000011 . now you can remove those 'n=5' bits starting at bit #'p=6', from the 'x' value by ANDing this bitmask with 'x', and result into a new variable say "x1"

finally, OR the results of "x1" and "y1" together to get your return value.

Here is the same thing, as pictorial. for illustration, i am showing the masked bits as dashes (-) even though they are actually 0's

y=  11101110  (0xEE, dec 238)
n=5 00011111  (get 5 bits through bitmask)
AND ________
y1= ---01110  (extracted from 'y'.  '-' are zeros)

x=  01010101  (0x55, dec 85)
p=6  ^        (bit #6)
n=5 10000011  (bitmask inverted and shifted left 'p+1-n' places)
AND ________
x1= 0-----01  (remaining bits from 'x'.  '-' are zeros)


('r' return value is the value of 'x' with the
extracted bits replaced with the bits from 'y')


x1= 0-----01  ('x', after 'n' bits at 'p' are deleted.)
y1= -01110--  (rightmost 'n' bits from 'y', shifted left 'p+1-n' places)
OR  ________
r=  00111001  (return value is 0x39, dec 57)

.

i think i did it

#include <stdio.h>
int setbits(int x, int y,int p,int n)
{
    x = (x >> (p+1-n)) & ~(~0 << n);
    y = y & (~0 << n);
    return x | y;
}
int main(void)
{
    int x;
    x=setbits(10,9,6,3);
    printf("%d",x);
    return getchar();
}

but see now problem i tried to do the other exerises but i alawys end up with -1 as result

#include <stdio.h>
unsigned getbits(unsigned x, int p, int n)
{
    return (x >> (p+1-n)) & ~(~0 << n);
}
unsigned int invert(int x,int p , int n) {
    x=getbits(x,8,3);
    
    return x=~x;
}
int main(void)
{
    int result;
    result=invert(5,8,3);
    printf("%d",result);   
    return getchar();
}

first i get the bits according then i changed that to invert them then i returned it but i alawys get -1 as result

you did not implement it right.

before declaring it 'done', you need to test the program with known values and known solutions. like the one i described x=85, p=6, n=5, y=238 ... the result should be 57. i'm quite certain the program you've posted will not give that result.

you're supposed to delete the bit field from 'x', but what you're doing is deleting everything around it. also, you should not be shifting the x value, but merely ANDing it with the proper bitmask.

you're also supposed to be keeping only the rightmost 'n' bits from 'y' ... contrariwise, you are deleting the rightmost 'n' bits from 'y' and keeping the rest.

.... i'm gonna let you figure out why, and how to fix it. re-read my post #6, above. the answer is there.

you also might want to make your variable types unsigned integers.


.

i solved it :D thanks alot mate

#include <stdio.h>
unsigned int getx(int x,int p,int n)
{
     return (x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n)))));
}
unsigned int gety(int y,int p,int n)
{
    return ((y & ~(~0 << n)) << (p + 1 - n));
}
unsigned int setbits(int x,int y,int p,int n)
{
     x=getx(x,p,n);
     y=gety(y,p,n);
     return (unsigned int) x | y;
}
int main(void)
{
    printf("result is %d",setbits(85,238,6,5));
    return getchar();
}

dam i rlly hated this chapter took me 2 days to solve it after reading your post like 30 times

commented: good job keeping at it. +11

but seriously man K&R need to write the excerises in better way it took me long time to understand the question itself

well, K&R is not really written for the beginner. It was written for people who were professional programmers in another language looking to learn the "new" language C.

obviously it's also older, and there have been a number of really good instructional books written since.

but admit it. you love this bitwise stuff now, don't you? :) it's great when you can solve a problem, without being handed the code.

yah i felt really cool when i was able to solve it :D.btw do you advice me to continue with K&R or get another book to continue with ?

K&R is a classic, but because it was written by the creators of C, not because it's a particularly good instructional book. there's nothing at all wrong with it, but you could spend your time more effectively.

so, if you want a physical book to have and to hold, I'm personally partial to the O'Reilly series, for any language.

If any person had to buy one and only one book on C, I'd say "C in a Nutshell" which is widely regarded as an invaluable desk reference: http://oreilly.com/catalog/9780596006976/ ... but this is not a book for beginners to learn from, it's a reference book.

the O'Reilly Book "Practical C Programming" is geared for beginners and has a lot of examples and explanatory text that "Nutshell" doesn't have. http://oreilly.com/catalog/9781565923065/

The Sams series is IMO like "O'Reilly Lite" ... It's definitely geared for beginners and has a lot of examples, but isn't quite as thorough. you can buy their book "Teach Yourself C in 21 Days" or you can read it online at http://neonatus.net/C/index.htm

an older book (circa 1992), that has been quite popular, "The C Book" has been made available as a free online reference http://publications.gbdirect.co.uk/c_book/

a hugely popular scientific book "Numerical Recipes in C" has a lot of advanced programming examples. it's very complex and not at all geared for the beginner. the legacy 2nd Edition has been made publicly available at http://www.nrbook.com/a/bookcpdf.php ... note that you need to jump through some hoops to install an Adobe plugin, in order to open up the chapters.


.

thanks again mate.

>do you advice me to continue with K&R or get another book to continue with ?
If you can handle K&R, I'd recommend going with it as your first weapon. If you can't handle K&R, I always liked "Pointers on C" by Kenneth Reek. I believe it's out of print now, but I'm sure you can find it on Amazon.

>the O'Reilly Book "Practical C Programming" is
Not a very good book. While it's nice that some good coding practices like fgets are used, the overall quality of the code is extremely poor, and the rest of the content isn't valuable enough to suffer the bad code (as it is with, for example, "Algorithms in C").

>"Teach Yourself C in 21 Days"
The whole genre of "Teach yourself in N units of time" is generally weak, though not especially bad.

I think it's overall a better choice to work your way through K&R than to risk learning bad habits from a "for beginners by beginners" book.

commented: harrumph. :) +11

>the O'Reilly Book "Practical C Programming" is
Not a very good book.

hmm... well, I must admit I've never actually used that book. i recommended it based on my experience with a variety of other books in the O'Reilly series, which are written by different authors but have IMO been consistently good.

I do notice now there is at least one person who gave a very similar criticism to "Practical C Programming" on the book reviews. And while I didn't say anything about it that isn't true, I shouldn't have implicitly recommended a book i hadn't actually read.

I absolutely stand by the "C in a Nutshell", though. I think it's a very thorough and well-written reference.


.

If you just want a reference, "C: A Reference Manual" is the best. A good beginner book is "C Primer Plus".

commented: C: A Reference Manual is extremely well reviewed. i'll have to check that out +11
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.