Учитывая двух целочисленных 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
}
Проблема состоит в том, что я не могу выяснить, как сделать маски правильно, когда все переменные, включая ширину целого числа, являются переменными.
Кто-либо знает, как записать вышеупомянутую функцию правильно?
Небольшое переключение даст вам нужные маски.
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) << P ??
2 ^ (N + 1) даст вам 1 в позиции N + 1 , Вытягивание 1 устанавливает все первые N битов, а затем сдвиг влево P раз перемещает всю компоновку на P позиций ...
Поскольку 2 ^ N эквивалентно 1 сдвигу влево N раз, все это выполняется следующим образом:
((1 << (N+1)) -1 ) << P
N и P могут отличаться друг от друга, но обычно это должно работать
Вы можете создать маски, используя:
int mask_y = ((1 << len) - 1) << pos;
int mask_x = ~mask_y;