C12位运算
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
12.1.4 ~ (按位取反)
对一个二进制数按位取反 ( 0 → 1 1 → 0 ),如 :
~ 00011001
11100110
例如 : 若一个整数 a 为16 位,要使 a 最低一位为 0。 a= a & 0177776 ; (常量与 a 的字长有关 )
最好的用法是以下表达式:(与 a 的字长无关)
(2) 设置一个右端4位全为1其余全为 0的数: ~(~0<<4) --- ~0=111111….11 , ~0<<4=1111….10000 , c = ~( ~0<<4)=0000….1111
(3) 将上述两个数进行 & 运算: d=b& c ;
a
15
87
43
0
b
15
43 0
程序如下:
void main( ) {
01110101
2. 用 0去与某些位异或 , 保留原值。 上例中前 4 位用 0去异或,保留原值 0111
3. 交换两个值 , 不用临时变量。 例如 : a=a ^ b ; b=b ^ a ; b=b ^ (a ^ b) =b ^ a ^ b =a ^ b ^ b=a a=a ^ b ; a=(a ^ b) ^ a =a ^ b ^ a=b ^ a ^ a=b
第十二章 位运算
第十二章 位运算
在计算机控制领域中常用到位运算。这是C语言的重要特色 。
12 . 1 位运算符和位运算
位运算-----二进制位的运算 (只能是整型和字符型数据,不能为实型数据)。
运算符
含义
& | ^
~(一目运算符)
<<
>>
按位与 按位或 按位异或
按位取反
左移运算符
右移运算符
12.1.1 & (按位与) ---- 两个数的相应位相与
程序如下:
void main( ) {
unsigned short a, b, c ; int n ; scanf("%d,%d",&a , &n) ; b = a << (16 - n) ; c = a>> n ; c=c|b; printf("%o \n%o \n", a, c); }
上机作业 (第十四周)
1. 输入任意结构体变量的数据,然后输出。 P234 4.(2) P244 2.(1) 2.(2)
程序运行:
51
[程序说明]
–12 –3
① 5 的 补 码 为 “ 00000000 00000101” , 右 移 2 位 后 得 “ 00000000 00000001”(左边空位补零),其十进制数为1。
② –12的补码为“11111111 11110100”,右移2位后得“1111111111 111101” ( 左 边 空 位 补 1 , 因 为 该 数 的 补 码 最 高 位 是 1 ) , 其 原 码 为 “10000000 00000011”十进制数符可以组合 成扩展的赋值运算符系统
如 : &= , |= , ^= , >>= , <<= ;
例如 : a &= b ; 相当于 a = a & b ; a >>= 2 ; 相当于 a = a>>2 ;
12.1.8 不同长度的数据进行位运算时,系统 将按右端对齐, 左端正数补 0,负数补 1
(1)运算规则 : 相应位都为1时,该位相与的结果为1,否则为0。
即
0&0=0 1&0=0
0&1=0 1&1=1
例如:3 & 5
3=00000011 & 5=00000101
00000001
值为 1
例如: (-3) & ( -5) ------先用补码表示,然后运算。
(-3)= 1 1 1 1 1 1 0 1 & (-5)= 1 1 1 1 1 0 1 1
1110011111111110
例 解释下列程序的输出结果。
#include <stdio.h> void main() { short x,y; x=5; y=x>>2; printf("%d %d\n",x,y); x=–12; y=x>>2; printf("%d %d\n",x,y); }
& 00111011 00010000
计算机中的控制字各个位表示某些设备的状态,状态发生变化, 各个位通过位运算改变数值。
12.1.2 | (按位或) --- 两个数的相应位按位或
(1)运算规则 : 相应位只要有一个为1时,该位相或的结果就为1,否则为0 。 即
0|0=0
1|0=1
例如:
0|1=1
异或---判断两个相应的位值是否为"异","异"则结果为1,否则为0
(1)运算规则 : 相应位的位值不同时(相异),值为1。
即
0^0=0
1^0=1
例如:
0^1=1
01011001
^ 00001111
01010110
1^1=0
(2) 用途 : 1. 用 1去与某些位异或 ,使特定位翻转。
01111010 ^ 00001111
11111001
值为 -7
(2) 用途 :
1. 用 0去与某一位,使某一位清 0 。例如:使低4位为0
11011001
& 11110000
11010000
低4位为0
2. 用 1 去与某一位,保留该位。例如:保留低4位
10101100
& 00001111
00001100
保留低4
3. 保留其中某些位,例如:保留第0, 1 , 3 , 4 , 5 位 01010100
b=a<< (16 - n);
n位
0 0 0…..0
(2) 将 a右移 n 位 c =a>>n;
c
n个0
左16-n位
(3) 将 c与 b按位或 c|b
c | b na位右n位 左a左161-6n-位n位
若 a = 1101010111111011 n=3 c = 0111101010111111
这里用二进制表示
12.1.6 >> (右移运算符)
将一个二进制数的各位全部右移若干位,移到右端的低位被舍去, 对无符号数 , 高位补0。
(对于负数,有“逻辑右移”和“算术右移”,视系统而定)
例如: a=a >> 2 ; (右移二位 )若 a=014 ; a二进制数为 0 0 0 0 1 1 0 0 a右移二位为 0 0 0 0 0 0 1 1
程序运行:
5
20
[程序说明]
–12 –48
① 5的二进制表示为“00000000 00000101”,将其左移2位后得 “00000000 00010100”,其十进制数为20。
② –12的补码为“11111111 11110100”,左移2位后得“111111 1111010000”,其原码为“10000000 00110000”十进制数为–48 。
其中:
a = a & ~1 ;
~1 = ~(0000000000000001)=1111111111111110 或
a = a & (a -1) ;
若
a= 00011011
& a-1=00011010
00011010
12.1.5 << (左移运算符)
将一个二进制数的各位全部左移若干位, 右端空位补0, 高位左移后溢出,舍去。
short x, y ; scanf("%d",&x) ; y= x>>4 ; y= y& ~ (~ 0<<4) ; printf("%x \n%x \n",x , y) ; }
例12.2 短整数 a 循环右移 n 位。 a
左左1166-n-n位位 n位n位
(1) 将 a 右端 n 位先放到 b中的左端 n 位:b
右移一位,相当于除2, 右移二位,相当于除 4 ,运算速度快得多。
逻辑右移:对无符号数 , 高位补 0; 算术右移:对于正数,高位补 0(0为符号位,称为符号位扩张)
对于负数,高位补 1( 1为符号位,也是符号位扩张) 0117771 >> 2 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 >> 2
1|1=1
00011001 | 00001111
00011111
(2) 用途:
1. 用 1去与某些位或,使某些位为 1。例如:
01011001 | 00001111
01011111
低 4 位设为 1
2. 用 0去与某些位或,保留原位。例如: 上例中 前4 位保留原位
12.1.3 ^ (按位异或) : 两个数相应位按位异或
例如 : a = a << 2 ; (左移二位)若 a=15 ,
a二进制数为 0 0 0 0 1 1 1 1 a 左移二位为 0 0 1 1 1 1 0 0 值为 60,
相当于 乘 4,运算速度快很多。
例 解释下列程序的输出结果。
#include <stdio.h> void main() { short x,y; x=5; y=x<<2; printf("%d %d\n",x,y); x=–12; y=x<<2; printf("%d %d\n",x,y); }
如果变量a 和 b有以下定义: long a ; int b ; 若进行位运算:a & b; 系统将两者按右端对齐,如果 b为正数,则左端补16个0, 如果为负数,左端应补1。
12.2 位运算举例
例12.1
取一短整数 a 的从右端开始的4--7位。 (即第4位至第7位共4个位)
(1) 使 a 右移4位 (使 a 的第4位右移到第0位) : b= a >> 4