K&R C运动帮助

K&R C运动帮助,c,binary,bit-manipulation,kr-c,C,Binary,Bit Manipulation,Kr C,我一直在阅读《K&R C编程语言》这本书,我一直在练习2-6,内容如下: 编写一个函数setbitsx,p,n,y,返回x,从位置p开始的n位设置为y的最右边n位,其他位保持不变 我很难理解他们要我做的事情。我看了一个可能的答案,但我还是不太明白。我想这句话让我很反感。谁能用另一种方式解释一下他们想让我做什么?我希望不同的措辞能帮助我理解在代码方面需要做什么。例如: int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010); i equa

我一直在阅读《K&R C编程语言》这本书,我一直在练习2-6,内容如下:

编写一个函数setbitsx,p,n,y,返回x,从位置p开始的n位设置为y的最右边n位,其他位保持不变

我很难理解他们要我做的事情。我看了一个可能的答案,但我还是不太明白。我想这句话让我很反感。谁能用另一种方式解释一下他们想让我做什么?我希望不同的措辞能帮助我理解在代码方面需要做什么。

例如:

int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011
我们取x 101中从位置5开始的3位,并用y 010中最右边的3位替换它们。

操作是位字段插入
其思想是y通常小于n位,但如果不是,则只使用n。在英语中,任务是使用n的字段宽度将y从p开始插入x。

将从p位置开始的x的n位替换为y的最右边的n位


也许您应该利用第2.9章中的getbits例程,可能的答案是没有注释的代码。难怪对你没有帮助

问题和回答者可能认为您熟悉位字段。这种事情在控制硬件寄存器的嵌入式编程中非常常见

比如说,有一个寄存器可以设置音频音量等。同时,它可以让你选择扬声器或麦克风之类的东西。这些位可能如下所示:

SSAAMXX-每个字母表示该数字内的一个位字段。要更改音量,必须更改AAA的值。现在,让我们假设您的程序中有一些东西可以调整音量。这是一个简单的控件,它总是返回一个介于0和7之间的数字。其格式如下所示:


XXXXX AAA-那么你的工作就是从这个称为y的数字中提取AAA位,并将它们设置到称为x上面的数字中,而不改变不是A的位。因此,问题是读取,取y的最右边的3位,并将它们设置为x,从第5位开始。记住,它们从零开始计算位。然后,在我们的例子中,3和5变成了原始问题中的n和p。

阐述了Avi的答案:

int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011
说你的i=0xAB。在二进制中,这是:10101011

让我们对每个位位置进行编号

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   1
最右边的位(最低有效位)是位置0。最左边最重要的是位置7

接下来的两个值,p和n,表示要修改从p位开始的n位。所以,如果p=5,n=3,你想从第5位开始,总共修改3位。这意味着第5,4,3位。101在本例中

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   1
                   |         |
                    ---------
               (Modifying these three bits)
我们如何修改它们?我们正在更换它们。用另一组3位。来自y的三个最低有效位

下面是y:

Position #: 7   6   5   4   3   2   1   0
Bit:        1   0   1   0   1   0   1   0 
最右边的位是位2,1,0。或值010。当然,如果n=6,那么您需要用101010(最右边的6位)替换i中的6位

因此,您的任务是从i中获取指定的位——在本例中为101——并用y-010中的指定位替换它们

如果这样做,则返回值为

10101010

这个怎么样

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

这是一个非常好的、彻底的解释。非常感谢,回答得很好。它也非常有用,只需获得一个示例输入和正确的答案,就可以验证它是否工作,这确实是一个非常好的解释。最后一行是答案?我不知道你传达了什么,但答案应该是:10011