Выбрать главу

Выставить все биты в 0

a.reset()

reset(pos)

Выставить бит pos в 0 a.rese

t(4)

Как мы уже говорили, необходимость создавать сложные выражения для манипуляции битовыми векторами затрудняет использование встроенных типов данных. Класс bitset упрощает работу с битовым вектором. Вот какое выражение нам приходилось писать в предыдущем разделе для того, чтобы “взвести” 27-й бит:

quiz1 |= 127;

При использовании bitset то же самое мы можем сделать двумя способами:

quiz1[27] = 1;

или

quiz1.set(27);

(В нашем примере мы не используем нулевой бит, чтобы сохранить “естественную” нумерацию. На самом деле, нумерация битов начинается с 0.)

Для использования класса bitset необходимо включить заголовочный файл:

#include bitset

Объект типа bitset может быть объявлен тремя способами. В определении по умолчанию мы просто указываем размер битового вектора:

bitset32 bitvec;

Это определение задает объект bitset, содержащий 32 бита с номерами от 0 до 31. Все биты инициализируются нулем. С помощью функции any() можно проверить, есть ли в векторе единичные биты. Эта функция возвращает true, если хотя бы один бит отличен от нуля. Например:

bool is_set = bitvec.any();

Переменная is_set получит значение false, так как объект bitset по умолчанию инициализируется нулями. Парная функция none() возвращает true, если все биты равны нулю:

sbool is_not_set = bitvec.none();

Изменить значение отдельного бита можно двумя способами: воспользовавшись функциями set() и reset() или индексом. Так, следующий цикл выставляет в 1 каждый четный бит:

for ( int index=0; index32; ++index )

if ( index % 2 == 0 )

bitvec[ index ] = 1;

Аналогично существует два способа проверки значений каждого бита – с помощью функции test() и с помощью индекса. Функция () возвращает true, если соответствующий бит равен 1, и false в противном случае. Например:

if ( bitvec.test( 0 ))

// присваивание bitvec[0]=1 сработало!;

Значения битов с помощью индекса проверяются таким образом:

cout "bitvec: включенные биты:\n\t";

for ( int index = 0; index 32; ++-index )

if ( bitvec[ index ] )

cout index " ";

cout endl;

Следующая пара операторов демонстрирует сброс первого бита двумя способами:

bitvec.reset(0);

bitvec[0] = 0;

Функции set() и reset() могут применяться ко всему битовому вектору в целом. В этом случае они должны быть вызваны без параметра. Например:

// сброс всех битов

bitvec.reset();

if (bitvec.none() != true)

// что-то не сработало

// установить в 1 все биты вектора bitvec

if ( bitvec.any() != true )

// что-то опять не сработало

Функция flip() меняет значение отдельного бита или всего битового вектора:

bitvec.f1ip( 0 ); // меняет значение первого бита

bitvec[0].flip(); // тоже меняет значение первого бита

bitvec.flip(); // меняет значения всех битов

Существуют еще два способа определить объект типа bitset. Оба они дают возможность проинициализировать объект определенным набором нулей и единиц. Первый способ – явно задать целое беззнаковое число как аргумент конструктору. Начальные N позиций битового вектора получат значения соответствующих двоичных разрядов аргумента. Например:

bitset 32 bitvec2( Oxffff );

инициализирует bitvec2 следующим набором значений:

00000000000000001111111111111111

В результате определения

bitset 32 bitvec3( 012 );

у bitvec3 окажутся ненулевыми биты на местах 1 и 3:

00000000000000000000000000001010

В качестве аргумента конструктору может быть передано и строковое значение, состоящее из нулей и единиц. Например, следующее определение инициализирует bitvec4 тем же набором значений, что и bitvec3:

// эквивалентно bitvec3

string bitva1( "1010" );

bitset 32 bitvec4( bitval );

Можно также указать диапазон символов строки, выступающих как начальные значения для битового вектора. Например:

// подстрока с шестой позиции длиной 4: 1010

string bitval ( "1111110101100011010101" );

bitset 32 bitvec5( bitval, 6, 4 );

Мы получаем то же значение, что и для bitvec3 и bitvec4. Если опустить третий параметр, подстрока берется до конца исходной строки:

// подстрока с шестой позиции до конца строки: 1010101

string bitva1( "1111110101100011010101" );

bitset 32 bitvec6( bitval, 6 );

Класс bitset предоставляет две функции-члена для преобразования объекта bitset в другой тип. Для трансформации в строку, состоящую из символов нулей и единиц, служит функция to_string():