Я использовал std::bitset<N>
в моей программе и нужно было найти младший значащий бит и сделать тривиальный расчет, как показано ниже:
int num = 5;
int res = num & (-num);
После чего наименее значимый бит num
установлен в res
и все остальное 0
«S. Это работает как -5
представлен в 2-х обозначениях дополнения.
Но я нашел std::bitset<N>
не имеет перегрузки оператора для одинарного operator -
который дал бы мне 2 дополнения для основных битов. Есть ли тривиальный способ реализации дополнения 2 с std::bitset<N>
? Я всегда мог использовать operator ~
переворачивать биты и перебирать их, делая сумму и перенос, начиная с LSB до MSB, но я искал решение, которое бы этого избежать.
std::bitset
не предоставляет никаких дополнительных методов. Так как вам нужно будет самостоятельно рассчитать дополнение operator~
и дополнительный цикл, просто пропустить operator~()
и искать LSB напрямую:
template <int N>
size_t least_significant_bit(const std::bitset<N> &bt){
for(size_t i = 0; i < bt.size(); ++i){
if(bt.test(i))
return i;
}
}
Я думаю, это не может быть более тривиальным, чем это;).
Обратите внимание, что результат least_significant_bit
не указано, если нет битов вообще. Можно было бы вернуться N
или измените цикл, чтобы проверить bt.test(N)
что приведет к исключению, но в конце концов не имеет смысла искать LSB в битовом наборе с нулевым значением.
Далее обратите внимание, вы можете использовать std::bitset<N>::operator[]
вместо std::bitset<N>::test
если вы не заинтересованы в пограничных проверках.
довольно удобный метод для выполнения дополнения до двух — найти наименее значимый 0 в вашем наборе битов, установить его в 1 и установить все менее значимые биты в 0.
псевдокод: (при условии, что set [0] — младший бит, если нет, переверните его)
int i = 0;
while (i < set.length && set[i])
{
set[i] = 0;
++i;
}
if (i < set.length)
set[i] = 1;