我试过用谷歌搜索并阅读维基百科,但没有人提到是否有命令用左/右的位序列填充位序列。例如,01000 将变为 010001111。我可以使用位掩码来做到这一点,但我的技术相当慢。那么在 C 中执行此操作的标准方法是什么?
问问题
1251 次
3 回答
1
要将值向右填充 1 位(最低有效位),您可以计算i
:n
(i + 1 << n) - 1
于 2012-10-05T06:16:57.747 回答
1
对于两者,我将使用x
原始数字和n
要填充的位数。
右(最不重要)填充:
我相信您可以逃脱的最少操作是:
(x + 1 << n) - 1
我是怎么到那里的?从转换x
( x << n
) 开始。现在它在我们想要的地方,但用0
s 填充。我们可以得到正确数量的1
s (1 << n) - 1
。现在,通常我们会按位或将它们放在一起。但是,由于1
其中一个中的所有 s 都与另一个中的 a0
对齐,我们也可以添加它们,让我们简化一下(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
,因为x
可能有1
s 在应该被填充的位置。另外,因为即使我们使用加法也无法简化它。
于 2012-10-05T06:34:53.023 回答
1
#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
于 2012-10-05T06:54:36.113 回答