ここですべてのビットが延伸マスクの4ビットを表す64ビットに16ビットマスクを延伸する方法は次のとおり
uint64_t x = 0x000000000000CF00LL;
x = (x | (x << 24)) & 0x000000ff000000ffLL;
x = (x | (x << 12)) & 0x000f000f000f000fLL;
x = (x | (x << 6)) & 0x0303030303030303LL;
x = (x | (x << 3)) & 0x1111111111111111LL;
x |= x << 1;
x |= x << 2;
が起動します下の16ビットのマスクを使用します。それは、このような、トップ32ビットにマスクの上位8ビットを移動:
0000000000000000 0000000000000000 0000000000000000 ABCDEFGHIJKLMNOP
は
0000000000000000 00000000ABCDEFGH 0000000000000000 00000000IJKLMNOP
なり、それはの下8ビットからマスクを延伸する同様の問題を解決します32ビット・ワード、上部および下部32ビットに同時に:
000000000000ABCD 000000000000EFGH 000000000000IJKL 000000000000MNOP
ビットが広がるされるまで、それはそうで16と内部4ビットのためにそれを行います。
を
000A000B000C000D 000E000F000G000H 000I000J000K000L 000M000N000O000P
その後二回自分自身で結果をオアすることにより、4ビットの間で「汚れ」、それらを:
AAAABBBBCCCCDDDD EEEEFFFFGGGGHHHH IIIIJJJJKKKKLLLL MMMMNNNNOOOOPPPP
あなたは48ビットでシフトする余分な最初のステップを追加することにより、128ビットにこれを拡張する可能性があり、 128ビット定数とマスク:あなたはまた、単にビットパターンを繰り返すことで、128ビットのうち他の定数を伸ばす必要があるだろう
x = (x | (x << 48)) & 0x000000000000ffff000000000000ffffLLL;
。しかし(私が知る限り)C++で128ビットの定数を宣言する方法はありませんが、おそらくマクロなどでそれを行うことができます(see this question)。また、上下の16ビットで別々に64ビットバージョンを使用するだけで、128ビットバージョンを作成することもできます。
マスキング定数をロードすることは困難であるか、またはあなたがシフトとマスキング使用して、以前のものからそれぞれ1を生成することができますボトルネックが判明した場合:
uint64_t m = 0x000000ff000000ffLL;
m &= m >> 4; m |= m << 16; // gives 0x000f000f000f000fLL
m &= m >> 2; m |= m << 8; // gives 0x0303030303030303LL
m &= m >> 1; m |= m << 4; // gives 0x1111111111111111LL
'_pdep_u32'は許可されていますか? – harold
17、78、...などの任意のビット数を伸ばしたいのですか、または16または32の倍数だけ必要ですか? – izlin
32の倍数 –