K&R C Exercise Help

寵の児 提交于 2019-12-09 12:36:50

问题


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.


回答1:


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




回答2:


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).




回答3:


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.




回答4:


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.




回答5:


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




回答6:


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;
}


来源:https://stackoverflow.com/questions/1415854/kr-c-exercise-help

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!