关于位操作

来源:互联网 发布:小学校园网络管理制度 编辑:程序博客网 时间:2024/06/10 19:56

位简介

简单来说,位就是10,在电脑中做的每一件事都是由它们组成的。电脑中所有的数据使用的是位。一个字节由8个位组成;一个字由两个字节组成,即16个位;而一个双字由四个字节组成,即32个位。

 0 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 1 1 1 0 0 0
||              |               |               |              ||
|+- bit 31      |               |               |       bit 0 -+|
|               |               |               |               |
+-- BYTE 3 -----+--- BYTE 2 ----+--- BYTE 1 ----+-- BYTE 0 -----+
|                               |                               |
+----------- WORD 1 ------------+----------- WORD 0 ------------+
|                                                               |
+--------------------------- DWORD -----------------------------+

C++位操作包括两种:传统的C语言方式的位操作和C++中利用bitset容器的位操作

   

一、传统的C方式位操作:

1.基本操作:

   使用一个unsigned int变量来作为位容器。

2.操作符:

|   按位或操作符:result=exp1|exp2;exp1exp2中对应位中至少有一个为1时,result中对应位为1,否则为0

&  按位与操作符::result=exp1&exp2;exp1exp2中对应位全为1时,result中对应位为1,否则为0

按位异或或操作符:result=exp1^exp2;exp1exp2中对应位不相同时,result中对应位为1,否则为0

反转操作符:将位容器中的所有位都反转,1变为00变为1

<< 按位左移操作符:exp<<n,将容器中所有的位向左移n位,空出的位用0填充。

>> 按位右移操作符:exp>>n,将容器中所有的位向右移n位,空出的位用0填充。

|=,&=,^= 分别对应|&^三种操作符的复合操作符。

3.常用操作

   这里我们假设有一个resultunsigned int变量用来储存32个学生的成绩(通过和不通过分别用01),这样result就有33位(result从右至左,从0开始计算位数,在这个例子中0位被浪费)。

(a) 将第27位设置为及格(设作1)其他位不变:

   result|(1<<27) //任意的位值与1作按位或操作其值为1,而与0作按位与操作其值不变

(b) 将第27位设置成不及格(设为0)。

   result&=~(1<<27) //任意的位值与0作按位与操作其值为0,而与1作按位与操作其值不变

(c) 反转第27位的值。

   result^=(1<<27) //任意的位值与1作按位异或操作其值为1,而与0作按位异与操作其值不变

 

二、C++中的bitset容器

1.头文件:

  #include <bitset>

2.声明一个容器:

 (a)声明一个指定位数的空容器(所有位设为0: bitset<int> bits;

 (b)声明一个指定位数并将指定的几个位初始化为相应值的容器: bitset<n> bits(int);

     bitdet<int> bits(string&)

总结:bitset模板类中类型参数传递容器的位数,而构造函数参数通过一个int或一个string&值来从右至左初始化容器中的相应值。

3.bitset的基本用法:

操作

功能

用法

Test(pos)

Pos位是否为1

a.test(4)

Any()

任意位是否为1

a.any()

None()

是否没有位为1

a.none()

Count()

值是1的位的个数

a.count()

Size()

位元素个数

a.size()

[pos]

访问pos

a.[pos]

Flip()

翻转所有位

a.flip()

Flip(pos)

翻转pos

a.flip(4)

Set()

将所有位置1

a.set()

Set(pos)

pos位置1

a.set(4)

Reset()

将所有位置0

a.reset()

Reset(pos)

pos位置0

a.reset(4)

 

4.bitset与传统C位操作及字符串的转换

   可以通过to_string()成员将容器转输出为一个string字符串,另外还可以用to_long()成员将容器输出到传统的用于C风格的位容器中。如:

  unsigned long bits = bits.to_long();

  sting str(bits.to_string());

5.bitset支持所有的位操作符。

C语言中常见的置位操作

如何对某一位置0或者置1
方法一:

写成宏,方便移植
#define setbit(x,y) x|=(1<<y) //X的第Y位置1
#define clrbit(x,y) x&=!(1<<y) //
X的第Y位清0

 

方法二:

C语言位运算除了可以提高运算效率外,在嵌入式系统的编程中,它的另一个最典型的应用,而且十分广泛地正在被使用着的是位间的与(&)、或(|)、非(~)操作,这跟嵌入式系统的编程特点有很大关系。我们通常要对硬件寄存器进行位设置

 

譬如,我们通过将AM186ER80186处理器的中断屏蔽控制寄存器的

第低6位设置为0(开中断2),最通用的做法是:

#define INT_I2_MASK 0x0040
wTemp = inword(INT_MASK);
outword(INT_MASK, wTemp &~INT_I2_MASK);

而将该位设置为1的做法是:

#define INT_I2_MASK 0x0040
wTemp = inword(INT_MASK);
outword(INT_MASK, wTemp | INT_I2_MASK);

判断该位是否为1的做法是:

#define INT_I2_MASK 0x0040
wTemp = inword(INT_MASK);
if(wTemp & INT_I2_MASK)
{
… /*
该位为
1 */
}

方法三:

int a|=(1<<x) //X就是某位需要置1的数字,如第四位置1为: a|=(1<<4)
int b&=~(1<<x) //
把某位置0

x=x|0x0100    //把第三位置1
x=x&0x1011    //
把第三位置0

#define BitGet(Number,pos) ((Number) >> (pos)&1)) //用宏得到某数的某位
#define BitGet(Number,pos) ((Number) |= 1<<(pos)) //
把某位置1
#define BitGet(Number,pos) ((Number) &= ~(1<<(pos)) //
把某位置
0
#define BitGet(Number,pos) ((Number) ^= 1<<(pos)) //
NumberPOS位取反

典型操作有:
WTCON |=  (1 << 5) //WTCON
的第五位清1
WTCON &= ~(1 << 5) //WTCON
的第五位清

与其它语言不同,C语言支持全部的位操作符(BitwiseOperators)。因为C语言的设计目的是取代汇编语言,所以它必须支持汇编语言所具有的运算能力。位操作是对字节或字中的位(bit)进行测试、置位或移位处理,这里字节或字是针对C标准中的charint数据类型而言的。位操作不能用于floatdoublelongdoublevoid或其它复杂类型