2010-12-13 8 views
4

これについては適切な方法はありますか?私はABCDとabcdを持っており、出力ビットはAaBbCcDdのようなものでなければなりません。悪用する任意の数学のトリックなし2つの16ビット整数を指定すると、それらのビットをインターリーブして1つの32ビット整数を形成できますか?

unsigned int JoinBits(unsigned short a, unsigned short b) { } 
+3

することは、これは宿題です?これまでに何を試しましたか? – chrisaycock

+0

16ビット値の1つをシフトアップします。あなたはプロセッサのエンディアンを知る必要があります – kenny

+1

@kenny:エンディアンは、任意のメモリから読み取られたビットパターンを解釈する必要はないので、エンディアンが作用するとは思いません。 – Lars

答えて

4
#include <stdint.h> 

uint32_t JoinBits(uint16_t a, uint16_t b) { 
    uint32_t result = 0; 
    for(int8_t ii = 15; ii >= 0; ii--){ 
    result |= (a >> ii) & 1; 
    result <<= 1; 
    result |= (b >> ii) & 1; 
    if(ii != 0){ 
     result <<= 1; 
    } 
    } 
    return result; 
} 

0

、私の最初の素朴な解決策は、ビットで出力数ビットを計算するためのデータ構造と同様のBitSetを使用することです。これは、lg(a)+ lg(b)ビットをループするので、複雑さが増します。

3

まず、あなたのビットを広める:

unsigned int Spread(unsigned short x) 
{ 
    unsigned int result=0; 
    for (unsigned int i=0; i<15; ++i) 
    result |= ((x>>i)&1)<<(i*2); 
    return result; 
} 

次に、このようにあなたの関数のオフセットを持つ2つのマージ:http://ideone.com/lXTqB:こちらもideone上でテスト

Spread(a) | (Spread(b)<<1); 
+0

は私にとってはちょっとラウンドしているようです...余分な2つの関数呼び出しと2つのループが必要です – vicatcu

0

一部のビット操作で可能ですが、正確なコードはプラットフォームのbyte orderによって異なります。 (最も一般的である)リトルエンディアンと仮定すると、あなたができる:

unsigned int JoinBits(unsigned short x, unsigned short y) { 
    // x := AB-CD 
    // y := ab-cd 

    char bytes[4]; 

    /* Dd */ bytes[0] = ((x & 0x000F) << 4) | (y & 0x000F); 
    /* Cc */ bytes[1] = (x & 0x00F0) | ((y & 0x00F0) >> 4); 
    /* Bb */ bytes[2] = ((x & 0x0F00) >> 4) | ((y & 0x0F00) >> 8); 
    /* Aa */ bytes[3] = ((x & 0xF000) >> 8) | ((y & 0xF000) >> 12); 

    return *reinterpret_cast<unsigned int *>(bytes); 
} 
+0

なぜこの答えが出てきたのか理解していますが、実際のビット単位のインタリーブではなく、 – vicatcu

+0

@vicatcu:あなたがそれを述べるまで、私はそれを考えなかった。私は、ABCDを16ビット整数として解釈する別の方法を考えることができませんでした。 – casablanca

1

あなたは真のビット単位のインターリーブをしたい場合は、最も簡単かつエレガントな方法は、このようになります。

unsigned int JoinBits(unsigned short a, unsigned short b) 
{ 
    unsigned int r = 0; 

    for (int i = 0; i < 16; i++) 
     r |= ((a & (1 << i)) << i) | ((b & (1 << i)) << (i + 1)); 

    return r; 
} 
関連する問題