|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 6bingame 于 2024-12-23 18:47 编辑
位运算
位运算应用于整型数据,即把整形数据看成是固定的二进制序列,然后对这些二进制序列进行按位运算。与其他的高级语言相比,位运算是c语言的特点之一。
位运算符
C语言提供了以下6种位运算符
位运算符 描述
& 按位与
| 按位或
^ 按位异或
~ 取反
<< 左移
>> 右移
说明:
(1)位运算符中除“~”以外,均为双目(元)运算符,即要求两侧各有一个运算量。
(2)运算量只能是整型或字符型的数据,不能为实型数据。
按位与运算符
按位与运算符”&“是双目运算符,其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0。即:
0&0=0,0&1=0,1&0=0,1&1=1
1.正数的按位与运算
例如,计算10&5。需要先把十进制数转换为补码形式,再按位与运算,计算如下。
0000 1010 10的二进制补码
& 0000 0101 5的二级制补码
0000 0000 按位与运算,结果转换为十进制后为0
所以10&5=0
2.负数的按位与运算
例如,计算-9&-5。
第1步:像转换为补码形式。
-9的原码:10001001,反码:11110110,补码:11110111
-5的原码:10000101,反码:11111010,补码:11111011
第2步:补码进行位与运算。
11110111 -9的二进制补码
& 11111011 -5的二进制补码
11110011 按位与运算
第3步:按结果转换为原码。
补码:11110011,反码:11110010,原码:10001101,原码:-13。所以-9&-5=-13。
3.按位与的作用
按位与运算通常用来对某些位清0或保留某些位。例如,把a的高8位清0,保留低8位,可以使用a&255运算(255的二进制数为0000000011111111)。
又例如,有一个数是01101101,我们希望保留从右边开始第3、第4位,以满足程序的某些要求,可以这样运算:
01101101
& 00001100
00001100
上式描述的就是为了保住指定位,进行的按位与运算。如果写成109&12。
按位或运算符
按位或运算符”|“是双目运算符,其功能是参与运算的两数各对应的两个二进位有一个为1,结果位就为1。
即:
0|0=0,0|1=1,1|0=1,1|1=1
参与运算的两个数均已补码出现。例如,10|5可写成如下算式。
00001010
| 00000101
00001111 15的二进制补码
所以10|5=13。
常用来将源操作数的某些位置为1,其他位置不变。
首先设置一个二进制掩码mask,执行s=s|mask,将其中的特定位置为1,其他位为0。
按位异或运算符
按位异或运算符"^"是双目运算符,其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异或时,结果为1。
即:
0^0=0,0^1=1,1^0=1,1^1=0
参与运算仍以补码出现,例如,10^5可写成如下的算式。
00001010
^ 00000101
00001111 15的二进制补码
所以10^5=15。
充分利用位异或的特性,可以实现以下效果。
(1)设置一个二进制掩码mask,执行s=s^mask,将特定位置为1,可以使特定位的值取反;设置掩码中特定的其他位是0,可以保留原值。
设有01111010,想使其低4位翻转,即1变为0,0变为1。可以将它与00001111进行^运算,即:
01111010
^ 00001111
01110101
(2)不引入第3变量,交换两个变量的值。
想将a和b的值互换,可以用以下赋值语句实现。
a=a^b;
b=b^a;
a=a^b;
分析如下:(按位异或满足交换率)
a=a^b;
b=b^a=b^a^b=b^b^a=0^a=a;
a=a^b=a^b^a=a^a^b=0^b=b;
假设a=3,b=4,验证如下。
a=011
^ b=100
a=111(a^b的结果,a变成7)
^ b=100
b=011(b^a的结果,b变成3)
^ a=111
a=100(a^b的结果,a变成4)
按位取反运算符
求反运算符"~"为单目运算符,具有右结合性,其功能是对参与运算数的各二进位按位求反。例如~9的运算为~(00001001),结果为(11110110),如果表示无符号数是246,如果表示有符号数是-10。
左移运算符
左移运算符"<<"是双目运算符,其功能是把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数。
1.无符号数的左移
如果是无符号数,则向左移n位时,丢弃左边n位数据,并在右边填充0。
2.有符号数的左移
如果是有符号数,则向左移动n位时,丢弃左边n位数据,并在右边填充0,同时把最高位作为符号位。
这种情况对于正数,跟上述的无符号数左移结果是一样的,不再分析。
右移运算符
右移运算符">>"是双目运算符,其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。
1.无符号数的右移
如果是无符号数,则向右移动n位时,丢弃右边n位数据,并在左边填充0
2.有符号数的右移
如果是有符号数,则向右移动n位时,丢弃右边n位数据,而左边填充的内容则依赖于具体的机器,可能是1,也可能是0。
例如,对于有符号数(10001010)来说,右移有两种情况。
(1)(1000 1010)>>2=(00100010)。
(2)(1000 1010)>>2=(11100010)。
|
|