2012-10-05 93 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應該填充的位置。另外,即使使用加法,我們也不能簡化它。