Установка битов в cpp_int

#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; сразу после цикла, и результат был идеальным, большое вам спасибо.