Преобразование двоичного в отрицательное целое число - PullRequest
0 голосов
/ 30 апреля 2018

Давайте гипотетически скажем, что у меня есть набор битов, которые я хочу преобразовать в int, но биты могут представлять отрицательное число дополнения до 2, например:

vector<bool> foo = { true, false, false, false, false, true, false, false }

Очевидно, что если установлено foo.front(), то число будет отрицательным. Что было бы лучшим способом преобразовать это в int?


В этом вопросе, похоже, нет ясности. Для справки я добавил мое решение для перебора здесь: https://stackoverflow.com/a/50108264/2642059 Я хочу выполнить то же самое, но в идеале с некоторой предоставленной функциональностью и не так много хакерских атак.

Ответы [ 3 ]

0 голосов
/ 01 мая 2018

Начальные установленные биты для числа, включая бит, который должен быть установлен для foo.front(), можно сгенерировать, выполнив: -(1 << size(foo) - 1). После этого вам нужно только сдвинуть оставшиеся биты.

Это, например, сгенерирует правильный номер независимо от того, установлен foo.front():

int i = size(foo) - 1;
const auto bar = accumulate(next(cbegin(foo)), cend(foo), foo.front() ? -(1 << i) : 0, [&](const auto val, const auto it) { return val + (it << --i); });

Живой пример

0 голосов
/ 01 мая 2018
std::vector<bool> foo;
//...
long long val=0;
for(auto& bit:foo){
    val<<=1;
    val+=bit;
};

if(foo.front())//sign extension
    val+=~0ll<<foo.size();
0 голосов
/ 30 апреля 2018

В двоичном обозначении дополнения минус числа - это дополнение плюс 1.

Когда foo.first() == true, преобразуйте все оставшиеся элементы в двоичные цифры, затем инвертируйте его и добавьте 1. Затем верните отрицательный результат.

Итак, в вашем примере остальные элементы соответствуют двоичному числу 0000000. Дополните это до 1111111, что составляет 127. Добавьте 1, и вы получите 128, а затем вернете -128. И действительно, значение -128 представляется как 10000000 в 8-битном двоичном дополнении.

Тип данных со знаком, который вы используете для этого процесса, должен быть как минимум на 1 бит больше, чем размер вектора, чтобы избежать переполнения при добавлении 1 к значению «все биты установлены». Поэтому, если ваш вектор может содержать до 32 элементов (включая знак), вам нужно использовать int64_t.

...