2016-11-17 10 views
1

ビットマスクを水平にフリップする簡単な方法はありますか? それは行う必要があり、次のよりエレガントな方法はあり水平方向にビットマスクを反転する

uint16 flipUint16Horizontally(uint16 bitmask) 
{ 
    uint16 flippedMask = 0; 
    for(unsigned int bit = 0; bit < 16; ++bit) 
    { 
     uint16 currentBit = (bitmask & (1 << bit)) >> bit; 
     flippedMask |= currentBit << (15 - bit); 
    } 
    return flippedMask; 
} 

0b1010101111001101 -> 0b1011001111010101 

まっすぐソリューションは、それは少しのビットやっているのでしょうか?

+0

エレガントな定義。 – 2501

+0

@ 2501:愚かな方法ではない;-) – m47h

+0

いくつかのアプローチがあります。しかし、そのアイデアのどれも「ワンライナー」と呼ばれることはありません。 – Codor

答えて

0

そこには、uint16というルックアップテーブルがあります。それは逆のための1つのライナーです、もちろん初期化にはもう少し作業が必要です。これはかなり大きなテーブルなので、必ずしも最速の方法ではありません。キャッシュミスの原因となる可能性のある比較的ランダムにインデックスを作成することになります。まだシンプルで、空き領域が少なくて済む:バイトを逆転させるルックアップテーブル。

return (bitreverse[x & 0xFF] << 8) | bitreverse[x >> 8]; 

もちろん、初期化には対処する必要がありますが、スピードはそれほど重要ではありません。

私の意見では、よりエレガントですが、最初の隣接ビットを反転させた後、隣接する2ビットのピースを反転させて、いくつかのビット単位の操作(および完全には理解できない剰余演算など)最後にすべてのビットが「グローバルに」反転されるまで、反転したものの幅を2倍にします。ところで、これらのステップを並べ替えることができます。また、1回の操作でILPを少なくして書く方法もあります。

x = ((x & 0x5555) << 1) | ((x >> 1) & 0x5555); // swap bits 
x = ((x & 0x3333) << 2) | ((x >> 2) & 0x3333); // swap 2-bit pieces 
x = ((x & 0x0f0f) << 4) | ((x >> 4) & 0x0f0f); // swap nibbles 
return (x >> 8) | (x << 8); // optimized last step 
関連する問題