Перезапись диапазона битов в целое число в общем виде
учитывая два целых числа 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 ответов
немного сдвига даст вам маски, которые вам нужны.
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);
}
сделайте маску для позиций P до P+N, взяв ((2^N+1) - 1)
2^ (N+1) дает вам 1 в позиции N+1, вычитание 1 устанавливает все первые N битов, а затем левое смещение P раз перемещает всю компоновку P позиций...
поскольку 2^ N равнозначно 1 левому сдвигу N раз, все это делается:
((1 << (N+1)) -1 ) << P
N и P могут быть отключены по одному, но, как правило, это должно работать