БлогNot. Битовые маски для пары флагов

Битовые маски для пары флагов

В продолжение темы и как ответ на вопрос, можно ли на С++ так же компактно работать с парой битовых флагов... По-моему, все нужные проверки содержатся в приложенной консольной программке:

#include <stdio.h>

#define A 0x01
#define B 0x02
 //Пусть младший бит - флаг A, второй бит - флаг B

void main () {
 int x=0;

 x|=A|B; //установка флагов A и B, x=3
 printf ("\nx=%02X",x); //для вывода текущего x

 x&=~(A|B); //сброс флагов A и B, x=0
 printf ("\nx=%02X",x);

 x=1;
 if (x&A) //проверка флага A
  printf ("\nфлаг A установлен");

 x=3;
 if ( (x&(A|B))==(A|B) ) //проверка, что установлены оба флага
     //все скобки нужны - приоритеты!
  printf ("\nустановлены оба флага");

 x=0;
 if ( !(x&(A|B)) ) //проверка, что сброшены оба флага
     //все скобки нужны - приоритеты!
  printf ("\nсброшены оба флага");

 x=2;
 if ( x&(A|B) ) //проверка, что установлен хотя бы 1 из флагов
  printf ("\nустановлен хотя бы 1 из флагов");

 x=1;
 if ( (x&(A|B))==A ) //проверка, что установлен только флаг A
     //все скобки нужны - приоритеты!
  printf ("\nустановлен только флаг A");

 int y=0;
 int diff= x^y; //проверка, какими флагами отличаются x и y
 if ( !(diff&A) ) printf ("\nФлаг А совпадает");
 if ( !(diff&B) ) printf ("\nФлаг B совпадает");

 getchar();
}

Как сделать, чтобы инвертировались (нули заменялись на единицы и наоборот) ровно N битов, начиная с позиции P, а все другие биты остались без изменений?

А вот:

#include <stdio.h>

void main () {
 unsigned int x=0x38, mask, N=3, P=3;
             //00111000 превратит в 0
 printf ("\n%02X",x);

 mask = ~(~0 << N) << P;
 x = (x & ~mask) | (~x & mask);

 printf ("\n%02X",x);
 getchar();
}

Как так вышло:

~0                 = 11111....11111
~0 << N         = 11111....11000  /* N нулей */
~(~0 << N)      = 00000....00111  /* N единиц */
~(~0 << N) << P = 0...01110...00
 /* N единиц на местах P+N-1..P */

09.12.2012, 20:42 [10331 просмотр]


теги: c++ программирование

К этой статье пока нет комментариев, Ваш будет первым