グーグルで検索してウィキペディアを読んでみましたが、ビットシーケンスを左右のシーケンスで埋めるコマンドがあるかどうかについては言及されていません。たとえば、01000は010001111になります。ビットマスキングを使用してこれを行うことはできますが、私のテクニックはかなり遅いです。では、Cでこれを行う標準的な方法は何ですか?
3 に答える
#include <limits.h>
#include <assert.h>
#include <stdio.h>
unsigned pad(unsigned pattern, unsigned patternLen,
unsigned leftBit, unsigned leftBitCnt,
unsigned rightBit, unsigned rightBitCnt)
{
unsigned r;
assert(leftBitCnt < sizeof(unsigned) * CHAR_BIT);
assert(rightBitCnt < sizeof(unsigned) * CHAR_BIT);
assert(patternLen < sizeof(unsigned) * CHAR_BIT);
assert(leftBitCnt + patternLen + rightBitCnt <= sizeof(unsigned) * CHAR_BIT);
r = (leftBit << leftBitCnt) - leftBit;
r <<= patternLen;
r |= pattern;
r <<= rightBitCnt;
r |= (rightBit << rightBitCnt) - rightBit;
return r;
}
void printBin(unsigned x)
{
unsigned i;
for (i = 0; i < sizeof(unsigned) * CHAR_BIT; i++)
printf("%u", (x >> (sizeof(unsigned) * CHAR_BIT - 1 - i)) & 1);
printf("\n");
}
int main(void)
{
printBin(pad(0x0F0, 12, 0, 2, 0, 2));
printBin(pad(0x0F0, 12, 0, 2, 1, 2));
printBin(pad(0x0F0, 12, 1, 2, 0, 2));
printBin(pad(0x0F0, 12, 1, 2, 1, 2));
return 0;
}
出力(ideone):
00000000000000000000001111000000
00000000000000000000001111000011
00000000000000001100001111000000
00000000000000001100001111000011
どちらも、x
元の数値とn
パディングするビット数に使用します。
右 (最下位) パディング:
あなたが逃げることができる最も少ない操作は次のとおりだと思います:
(x + 1 << n) - 1
どうやってそこに着いたのですか?シフトx
オーバー ( x << n
) から始めます。これで目的の場所になりましたが、s が埋め込まれてい0
ます。1
で適切な数のs を取得できます(1 << n) - 1
。さて、通常はビットごとに、またはそれらを一緒にします。ただし、一方のすべての が他方1
の a と並んで0
いるため、それらを追加することもできます(x << n) + (1 << n) - 1 = (x + 1 << n) - 1
。+
/は/操作の-
前に発生することに注意してください。<<
>>
左 (最も重要なパディング):
x | -1 << BIT_WIDTH - n
まず、-1
すべてのものなので使用します。これは署名されていると思います。そうでない場合は、MAX_INT
、または のタイプの相対定数を使用しx
ます。1
次に、すべてのs をスロット上でシフトするだけで、正しい場所にBIT_WIDTH - n
n が残ります。1
ここでは、パディングされるはずの位置に s が存在する可能性がx
あるため、ビットごとに or を使用する必要があります。また、足し算を使っても簡単にできないからです。x
1
値の右i
にn
1 ビット (最下位ビット) を埋め込むには、次のように計算できます。
(i + 1 << n) - 1