#c #boost #bit-manipulation #boost-multiprecision
#c #повышение #манипулирование битами #повышение -многопоточность
Вопрос:
Глупый вопрос, но работает ли установка битов в a cpp_int
из boost
библиотеки так же, как обычные числа?
Для instrance я попытался установить несколько битов для числа следующим образом:
vector<bool> bits; //contains 000000000000011010001100101110110011011001101111
cpp_int M = 0;
int k = 48;
for(bool b : bits) M ^= (-b ^ M) amp; (1UL << k--);
bits.clear();
bits = toBinary(M); //contains 11001011101100110110011011111
toBinary(cpp_intamp;x)
Метод, который у меня есть, получает биты из числа самым простым способом:
vector<int> toBinary(cpp_intamp;x) {
vector<int> bin;
while (x > 0) {
bin.push_back(int(x % 2));
x /= 2;
}
reverse(bin.begin(), bin.end());
return bin;
}
Я могу понять потерю 14 нулей в начале, чего я не понимаю, так это почему теряются не 14, а 20 целых битов. Я довольно новичок в boost
библиотеке, так что, скорее всего, это ошибка новичка.
Ответ №1:
Вероятно unsigned long
, в вашей системе 32 бита. Таким образом, первые маски (1UL << k--)
, сгенерированные с k--
48 до 32, не соответствуют вашим ожиданиям (это неопределенное поведение).
Вы можете исправить это, используя более крупный тип, например unsigned long long
, like M ^= (-b ^ M) amp; (1ULL << k--);
.
Если у вас более 64 бит, вы, вероятно, можете использовать cpp_int
для большего количества битов, например M ^= (-b ^ M) amp; (cpp_int(1ULL) << k--);
, или более экономичное решение, например:
cpp_int mask = 1;
mask <<= bits.size();
for (bool b : bits) {
M ^= (-b ^ M) amp; mask;
// Though that can really be `if (b) M |= mask;`
mask >>= 1;
}
Комментарии:
1. Почти идеально, однако результат 11010001100101110110011011001101111 (0), что надоедливого 0 в скобках в конце на самом деле не должно быть.
2. Конечно, это не имеет большого значения, я просто добавил M >>= 1; сразу после цикла, и результат был идеальным, большое вам спасибо.