Перезапись диапазона битов целым числом в общем виде - PullRequest
8 голосов
/ 12 апреля 2010

Учитывая два целых числа X и Y, я хочу перезаписать биты в позиции P в P + N.

Пример:

int x      = 0xAAAA; // 0b1010101010101010
int y      = 0x0C30; // 0b0000110000110000
int result = 0xAC3A; // 0b1010110000111010

У этой процедуры есть имя?

Если у меня есть маски, операция достаточно проста:

int mask_x =  0xF00F; // 0b1111000000001111
int mask_y =  0x0FF0; // 0b0000111111110000
int result = (x & mask_x) | (y & mask_y);

Что я не могу понять, так это как написать это универсальным способом, например, в следующей универсальной функции C ++:

template<typename IntType>
IntType OverwriteBits(IntType dst, IntType src, int pos, int len) {
// If:
// dst    = 0xAAAA; // 0b1010101010101010
// src    = 0x0C30; // 0b0000110000110000
// pos    = 4                       ^
// len    = 8                ^-------
// Then:
// result = 0xAC3A; // 0b1010110000111010
}

Проблема в том, что я не могу понять, как правильно создавать маски, когда все переменные, включая ширину целого числа, являются переменными.

Кто-нибудь знает, как правильно написать вышеуказанную функцию?

Ответы [ 4 ]

10 голосов
/ 12 апреля 2010

Небольшое смещение даст вам необходимые маски.

template<typename IntType>
IntType OverwriteBits(IntType dst, IntType src, int pos, int len) {
    IntType mask = (((IntType)1 << len) - 1) << pos;
    return (dst & ~mask) | (src & mask);
}
1 голос
/ 12 апреля 2010

Этот сайт посвящен хищническим взломам:

http://graphics.stanford.edu/~seander/bithacks.html

0 голосов
/ 12 апреля 2010

Сделайте маску для позиций от P до P + N, взяв ((2 ^ N + 1) - 1) << P ?? </p>

2 ^ (N + 1) дает вам 1 в позиции N + 1, Субтракт 1 устанавливает все первые N битов, а затем сдвиг влево P раз перемещает все позиции P компоновки ...

Поскольку 2 ^ N эквивалентно 1 левому сдвигу N раз, все это делается:

 ((1 << (N+1)) -1 ) << P

N и P могут быть выключены по одному, но обычно это должно работать

0 голосов
/ 12 апреля 2010

Вы можете создать маски, используя:

int mask_y = ((1 << len) - 1) << pos;
int mask_x = ~mask_y;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...