2011-09-16 8 views
2

私は32ビットの符号なし整数を持っています。私は与えられた位置でビットを抽出し、それらのビットから新しい数値を作る必要があります。たとえば、0xFFFFFFFFがあり、ビット0,10,11が必要な場合、私の結果は7(111b)になります。ビット操作を使用したビットの抽出

これは私の試みですが、ビットを正しく抽出しますが、正しい結果を作成しません。私は1つ左の結果をシフトしていて、抽出したビットとANDingしていますが、これは間違っていますか?

これを行うにはもっとエレガントな方法がありますか?

#define TEST 0xFFFFFFFF 

unsigned int extractBits(unsigned short positions[], unsigned short count, unsigned int bytes) 
{ 
    unsigned int result = 0; 
    unsigned int bitmask = 0; 
    unsigned short bit = 0; 
    int i = 0; 

    for(i = 0; i < count; i++) { 
     bitmask = 2 << (positions[i] -1); 
     if(bitmask == 0) bitmask = 1; 

     bit = bytes & bitmask; 
     bit = bit >> positions[i]; 

     result = result << 1; 
     result = result & bit; 
    } 

    if(result != 31) { 
     printf("FAIL"); 
    } 

    return result; 
} 

int main(void) 
{ 
    unsigned short positions[5] = {8, 6, 4, 2, 0}; 
    unsigned int result = extractBits(positions, 5, TEST); 

    printf("Result: %d\n", result); 

    return 0; 
} 
+0

'2 <<(positions [i] -1)'はむしろ '1 << positions [i]'であるべきです。負の数でシフトすることはノーである。 –

答えて

1

を、ビット変数をマスクにする理由はありません。ちょうど単位ビットに所望のビットをシフトし、例えば1のマスクを使用する:

... 
result = (2*result) | ((bytes >> positions[i]) & 1); 
... 

多くのコンパイラは、2*resultresult<<1で同じコードを生成するので、好きな方を使用します。

インターフェイスを設計していて、positions[]countshortの整数を使用する理由がない場合は、そうしないでください。一貫性を保ち、すべての整数を同じ方法で指定します。

2

、未テストコードを注意してください:あなたは、個々のビットをオフに選んでいるので

for(i = 0; i < count; i++) 
{ 
    bitmask = 1 << positions[i]; 
    bit = (bytes & bitmask)!=0; 
    result = (result << 1)|bit; 
} 
+0

ありがとう、完璧に動作:) – Jason