битовый набор для более чем 32 бит?

Мне нужно использовать битовые флаги с более чем 32 битами (33, если быть точным прямо сейчас). Я попробовал и обнаружил, что std::bitset не обрабатывает более 32 бит (ulong). Должен ли я использовать вектор или есть способ заставить битовый набор работать?

В этом проекте я ограничен С++ 98, поэтому я не могу использовать boost.

Спасибо.

Редактировать:

Я хотел бы сделать что-то вроде этого:

const uint64    kBigNumber = 1LL << 33;
std::bitset<33> myBitSet;
...
switch(myBitSet) {
    case kBigNumber:
    // do something
    ...
}

person Stephen Chu    schedule 31.08.2010    source источник
comment
Предположительно, вам нужно будет выполнять несколько операций с набором битов для отдельных 32-битных значений?   -  person Gian    schedule 31.08.2010
comment
На самом деле, я хотел бы иметь возможность выполнять побитовые операции между наборами битов и 64-битными константами. Что-то вроде if(my33bitset & kA64bitConst) {...}. Также будет здорово использовать 64-битные константы в предложении case оператора switch.   -  person Stephen Chu    schedule 31.08.2010
comment
Как можно было ограничиться C++98?   -  person Puppy    schedule 31.08.2010
comment
@DeadMG: Это устаревший проект, в процессе сборки которого я мало что могу сделать.   -  person Stephen Chu    schedule 31.08.2010


Ответы (4)


Я только что повторно протестировал std::bitset с 65-битной версией, и на моем 32-битном Linux он работает нормально и, как и ожидалось.

Заметным исключением является метод to_ulong(), который выдает исключение, если какой-либо установленный бит будет усечен во время преобразования. Теперь я думаю об этом, и это довольно очевидно: нет другого способа, как предотвратить получение приложением усеченных данных. И поведение также задокументировано.


В Edit с переключателем/регистром. Зачем вам тогда std::bitset? Ваша платформа, по-видимому, уже поддерживает 64-битные числа - используйте их. std::bitset предназначен для использования в качестве облегченного битового массива со статическим выделением памяти. Он не предназначен для использования в качестве замены числа.

person Dummy00001    schedule 31.08.2010
comment
Сейчас я использую простой 64-битный беззнаковый. Я изучаю различные способы сделать это, а также планирую будущее, где флаги могут быть больше 64 бит. - person Stephen Chu; 31.08.2010
comment
Вы можете использовать только целые типы для переключения/регистра в C/C++. uint64_t (или любой другой самый широкий целочисленный тип, поддерживаемый вашим компилятором) — это то, на что вы сможете перейти в 32-битной архитектуре. И более 64 флагов - это звучит как плохая идея. Спросите здесь, на SO, как этого избежать. - person Dummy00001; 31.08.2010

std::bitset должен работать с более или менее произвольными размерами - он не обычно ограничен размером unsigned long (хотя это может выглядеть так, потому что есть конструктор, который строит набор битов на основе битов в беззнаковое длинное).

Если это не сработает, vector<bool> может оказаться для вас полезным, хотя вы должны знать, что это в значительной степени vector только по названию — на самом деле он не является контейнером (т. е. не соответствует к обычным требованиям контейнера).

person Jerry Coffin    schedule 31.08.2010

Подойдет ли вам std::vector<bool>? Его можно изменять в размерах, он работает достаточно быстро и занимает мало места. Это также часть STL.

person andand    schedule 31.08.2010
comment
Тем не менее, не совместимый с STL, захватывающе - person Alice Purcell; 31.08.2010

Вы можете использовать to_string в своем наборе битов и скрыть его, используя strtoull

const uint64    kBigNumber = 1LL << 33;
std::bitset<33> myBitSet;
...
unsigned long long bitSetLong = strtoull(myBitSet.to_string<char,char_traits<char>,allocator<char> >().c_str(), NULL, 2);
switch(bitSetLong) {
    case kBigNumber:
    // do something
    ...
}

Обратите внимание, что приведенное выше может работать только до 64 бит.

person aeh    schedule 31.08.2010