K&R C Exercise Help

2019-03-27 19:09发布

I've been going through the K&R C Programming Language book and I'm stuck on Exercise 2-6 which reads:

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'm having trouble understanding the exact thing they're looking for me to do. I looked at a possible answer here, but I still don't really understand. I think it's the wording that's throwing me off. Can anyone maybe explain what they're looking for me to do in a different way? I'm hoping that different wording will help me understand what I need to do code wise.

6条回答
别忘想泡老子
2楼-- · 2019-03-27 19:42

That "possible answer" is just code without comments. No wonder it didn't help you.

The question (and probably the answerers) assume that you are familiar with bit fields. This sort of thing is very common in embedded programming where you control hardware registers.

Say there's a register that sets the audio volume level, among other things. It might, at the same time, let you select speakers or microphones and things like that. The bits might look like this:

ssAAAmxx -- Each letter represents a bitfield within that number. To change the volume, you have to alter the value of "AAA". Now, lets say you have something in your program that lets you adjust the volume. It's a simple control, and it always returns a number between 0 and 7. The format for that looks like this:

xxxxxAAA -- You job then, is to take the AAA bits from this (call it "y"), and set them into that number above (call it "x"), without altering the bits that aren't the A's. Thus, the problem would read, "Take the rightmost 3 bits of y, and set them into x, starting with bit 5 (remember, they count bits from zero). Then, 3 and 5 in our example become n and p in the original problem.

查看更多
相关推荐>>
3楼-- · 2019-03-27 19:42

The operation is "bitfield insert"

The idea is that y would usually be fewer than n bits, but in case it's not, only use n. In english, the task is to insert y into x beginning at p, using a field width of n.

查看更多
你好瞎i
4楼-- · 2019-03-27 19:44

For example:

int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011

We take the 3 bits beginning at position 5 in x (101), and replace them with the rightmost three bits from y (010).

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-03-27 19:49

Replace n bits of x, starting at p position, with the rightmost n bits of y.

And probably you should take advantage of the getbits() routine in chapter 2.9

查看更多
Deceive 欺骗
6楼-- · 2019-03-27 19:53

Expounding on Avi's answer:

int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011

Say your i = 0xAB. In binary, this is: 10101011

Let's number each of the bit positions.

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   1

The right-most bit (the least-significant) is position "0". The left-most (most-significant) is position "7".

So the next two values, p and n, are saying "You want to modify n bits starting at bit p." So if p=5 and n=3, you want to start at bit number 5, and in total you're modifying 3 bits. Which means bits 5, 4, 3. "101" in this example.

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   1
                   |         |
                    ---------
               (Modifying these three bits)

How are we modifying them? We are replacing them. With another set of 3 bits. The three least-significant bits from y.

So here's y:

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   0 

And the right-most bits would be bits 2, 1, 0. or the value "010". Of course, if the value of n=6, then you'd want to replace those six bits from i with "101010" - the rightmost 6 bits.

So your task is to take the specified bits from i - in this case, "101" - and replace them with the specified bits in y - "010".

If you do this, then your return value is

1 0 1 0 1 0 1 0

查看更多
smile是对你的礼貌
7楼-- · 2019-03-27 19:55

How about this?

unsigned int
setbits(unsigned int x, int p, int n, unsigned int y)
{
    char buffer[65];

    unsigned x1 = x >> (p + 1);
    x1 <<= (p + 1);

    /*
     * x1 now contains all the bits before position 'p'.
     */

    unsigned x2 = y & ~(~0 << n);
    x2 <<= (p + 1) - n;

    /*
     * x2 now contains the rightmost 'n' bits of 'y', left shifted (p + 1) - n bits.
     */
    unsigned x3 = x & ~(~0 << ((p + 1) - n));

    /*
     * x3 now contains the rightmost (p + 1) - n bits.
     */

    return x1 | x2 | x3;
}
查看更多
登录 后发表回答