Позвольте мне сначала объяснить причину проблемы, которую я изложу.У меня есть вектор v
слов без знака с информацией, хранящейся в битах, а также слово w
некоторого, возможно, другого типа без знака.Я хотел бы поместить len
бит из v
в w
, начиная с i
th LSB w
.Например, рассмотрим нижеприведенный случай, когда я представлял слова в виде битов только для пояснения.
T1 w = 10110100;
vector<T2> v = [11, 00, 10, 01];
T1 len = 5;
T1 start = 2;
T1 dst_digits = 8;
T1 src_digits = 2;
10110100 -> 10111100 -> 10001100 -> 11001100
Понятно, что нам нужно будет перебрать v
и добавить биты к w
одно слово за раз.Один из способов сделать это - следующий
template<class T>
T _blend(T a, T b, T start, T len) {
// Replaces len bits of a by the ones of b starting at start
}
auto it = std::begin(v);
while (len > 0) {
w = _blend(w,
(T1) ((T1) *first) << start),
start,
std::min(len, src_digits)
);
start += std::min(len, src_digits);
++first;
len -= std::min(len, src_digits);
}
Я довольно новичок в C ++, и приведенный выше код является упрощенным кодом, но основная идея остается в силе.У меня это работает и сейчас.Тем не менее, я считаю (T1) ((T1) *first) << start)
безобразнымЕсли я не включу первое приведение, операция сдвига будет переведена в int
или long
, а затем будет несовместима с другими типами _blend
.Если я не включу второй актерский состав, я могу превышение *first
(в случае, когда dst_digits > src_digits
и start > src_digits
).
Теперь мой вопрос: насколько дорогодва (T1)
преобразования?Мое предположение не так дорого, как другие вещи, такие как вызов std::min
или другие операторы в цикле.Я спрашиваю только потому, что, исходя из Python, видеть что-то вроде (T1) ((T1) *first) << start)
выглядит просто неестественно, и мне интересно, является ли это просто следствием C ++ с минимальными накладными расходами или нет, и есть ли просто лучший способ сделать это?это.