2012-10-05 94 views
1

我试过用Google搜索并阅读维基百科,但是他们中没有人提到是否有命令在左/右上填充一个位序列。例如,01000会变成010001111.我可以通过位掩码来做到这一点,但我的技术很慢。那么在C中做这件事的标准方式是什么?左右填充位表示法

回答

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 
1

要填充值in 1位权(至少显著位),你可以计算出:

(i + 1 << n) - 1 
1

对于这两个,我会用x为原来的号码和n的位数垫。

右(最低显著)填充:

我相信最少的操作,您可以逃脱是:

(x + 1 << n) - 1 

我怎么到那里?从x开始(x << n)。现在它在我们想要的位置,但填充了0 s。我们可以通过(1 << n) - 1获得1的正确数量。现在,我们通常会按位或将它们放在一起。但是,由于其中一个中的所有1与另一个中的0对齐,所以我们也可以添加它们,这使我们简化了:​​。请记住,+/-发生在<</>>操作之前。

左(最显著填充):

x | -1 << BIT_WIDTH - n 

首先,我们使用-1因为它是所有的人。我假设这是签署的;如果不是,则使用MAX_INTx类型的相对常数。然后,简单地将所有1转移到BIT_WIDTH - n槽位,这使我们在正确的位置留下了n 1s。在这里,我们应该按位或x,因为x可能有1 s应该填充的位置。另外,即使使用加法,我们也不能简化它。