Вот способ растяжения 16-битовая маски в 64 бита, где каждый бит представляет 4 бит растянутой маски:
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 бит. Затем он перемещает верхние 8 бит маски в верхние 32 бит, как это:
0000000000000000 0000000000000000 0000000000000000 ABCDEFGHIJKLMNOP
становится
0000000000000000 00000000ABCDEFGH 0000000000000000 00000000IJKLMNOP
Затем он решает подобную проблему растяжения маску из нижних 8 бит 32-битное слово, к верхнему и нижнему 32-бит одновременно:
000000000000ABCD 000000000000EFGH 000000000000IJKL 000000000000MNOP
Затем он делает это на 4 бита внутри 16 и так далее до тех пор, пока биты разложены:
000A000B000C000D 000E000F000G000H 000I000J000K000L 000M000N000O000P
Затем он «мажет» их через 4 бита на ORing результат с собой дважды:
AAAABBBBCCCCDDDD EEEEFFFFGGGGHHHH IIIIJJJJKKKKLLLL MMMMNNNNOOOOPPPP
Вы можете расширить это до 128 бит, добавляя дополнительный первый этап, на котором сдвиг на 48 бит и маска с 128-бит константой:
x = (x | (x << 48)) & 0x000000000000ffff000000000000ffffLLL;
Вы бы также, чтобы растянуть другие константы из на 128 бит, просто повторяя битовые шаблоны. Однако (насколько я знаю) нет способа объявить 128-битную константу в C++, но, возможно, вы могли бы сделать это с помощью макросов или чего-то еще (see this question). Вы также можете сделать 128-битную версию, просто используя 64-разрядную версию в верхнем и нижнем 16 бит отдельно.
При загрузке константы маскирования оказывается трудности или узким местом вы можете создать каждый из предыдущего с помощью сдвига и маскирования:
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. –