K&R C Exercise Help

瘦欲@ 提交于 2019-12-03 13:55:11
poundifdef

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

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

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.

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.

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

rakesh

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