K& R Cエクササイズヘルプ
-
06-07-2019 - |
質問
K& R Cプログラミング言語の本を読んでいますが、演習2-6にこだわっています。
関数setbits(x、p、n、y)を作成し、位置pで始まるnビットをyの右端のnビットに設定し、他のビットは変更せずにxを返します。
彼らが私に求めていることを正確に理解するのに苦労しています。 こちらで考えられる答えを調べましたが、まだそうではありませんわかる。私はそれが私をスローしている言葉遣いだと思います。誰かが私に求めていることを別の方法で説明できますか?異なる言葉遣いが、コードを賢くするために必要なことを理解するのに役立つことを願っています。
解決
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」です。
次の2つの値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の下位3ビット。
だからここに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の場合、iの6ビットを「101010」に置き換える必要があります。 -右端の6ビット。
したがって、タスクはiから指定されたビットを取得することです。この場合、「101」 -そして、それらをyの指定されたビットに置き換えます-" 010"。
これを行う場合、戻り値は
1 0 1 0 1 0 1 0
他のヒント
例:
int i = setbits(0xAB = b10101011, 5, 3, 0xAA = b10101010);
i equals 0x93 = b10010011
xの位置5から始まる3ビット(101)を取得し、yの右端の3ビット(010)に置き換えます。
その"可能な回答"コメントなしのコードです。それがあなたを助けなかったのも不思議ではありません。
質問(およびおそらく回答者)は、ビットフィールドに精通していることを前提としています。この種のことは、ハードウェアレジスタを制御する組み込みプログラミングでは非常に一般的です。
オーディオボリュームレベルなどを設定するレジスタがあるとします。同時に、スピーカーやマイクなどを選択できる場合があります。ビットは次のようになります。
ssAAAmxx-各文字は、その番号内のビットフィールドを表します。音量を変更するには、「AAA」の値を変更する必要があります。次に、プログラムに音量を調整できるものがあるとしましょう。これは単純なコントロールであり、常に0〜7の数値を返します。その形式は次のようになります。
xxxxxAAA-次に、AAAビットを取り出し(「y」と呼びます)、上記の番号に設定し(「x」と呼びます)、ビットを変更せずにAの。したがって、問題は、「yの右端の3ビットを取得し、ビット5から開始してxに設定する(ゼロからビットをカウントすることを忘れないでください)」と読み取ります。次に、この例の3と5は、元の問題のnとpになります。
操作は「ビットフィールド挿入」です
アイデアは、通常 y は n ビットよりも少ないということですが、そうでない場合は n のみを使用してください。英語では、タスクは n のフィールド幅を使用して、 p で始まる y を x に挿入することです。
xのnビットを、p位置から開始し、yの右端のnビットに置き換えます。
そしておそらく2.9章の getbits()
ルーチンを利用すべきでしょう
これはどうですか?
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;
}