白 雪 飞
baixf@ustc.edu.cn
中国科学技术大学电子科学与技术系
Dept,of Elec,Sci,& Tech.,USTC
Fall,2003
第 9章 位 运 算
C语言程序设计 - 第 9章 位运算 2
目 录
? 位运算和位运算符
? 位运算举例
C语言程序设计 - 第 9章 位运算 3
位运算
? 按二进制位进行运算
? 位运算的运算对象是二进制的位
? 位运算速度快,效率高,节省存储空间
? 只能对整型数据 (包括字符型 )进行位运算
? 负数以补码形式参与运算
? 注意与逻辑运算区别
C语言程序设计 - 第 9章 位运算 4
位运算符 (Bitwise Operators)
运算符 名称 举例 优先级
~ 按位取反 ~flag (高 )
(算术运算符 )
<< 左移 a << 2
>> 右移 b >> 3
(关系运算符 )
& 按位与 flag & 0x37
^ 按位异或 flag ^ 0xC4
| 按位或 flag | 0x5A (低 )
(赋值运算符 )
C语言程序设计 - 第 9章 位运算 5
按位与 (Bitwise AND)
? 运算规则
?0 & 0 = 0;
?0 & 1 = 0;
?1 & 0 = 0;
?1 & 1 = 1;
? 用法
?按位清零
?保留某些指定位
C语言程序设计 - 第 9章 位运算 6
按位与举例
? 运算举例
1010,1101 (0xAD)
& 0110,1001 (0x69)
0010,1001 (0x29)
? 按位清零、保留
xxxx,xxxx_____
& 0110,0010 (0x62)
0xx0,00x0_____
C语言程序设计 - 第 9章 位运算 7
按位或 (Bitwise Inclusive OR)
? 运算规则
?0 | 0 = 0;
?0 | 1 = 1;
?1 | 0 = 1;
?1 | 1 = 1;
? 用法
?按位置一
C语言程序设计 - 第 9章 位运算 8
按位或举例
? 运算举例
1010,1101 (0xAD)
| 0110,1001 (0x69)
1110,1101 (0xED)
? 按位置一
xxxx,xxxx_____
| 0110,0010 (0x62)
x11x,xx1x_____
C语言程序设计 - 第 9章 位运算 9
按位异或 (Bitwise Exclusive OR,XOR)
? 运算规则
?0 ^ 0 = 0;
?0 ^ 1 = 1;
?1 ^ 0 = 1;
?1 ^ 1 = 0;
? 说明
?相“异”则为 1,相“同”则为 0
?相当于按位且无进位的加法
C语言程序设计 - 第 9章 位运算 10
按位异或用法举例
? 特定位翻转
1010,1101 (0xAD)
^ 0110,1001 (0x69)
1100,0100 (0xC4)
? 与 0相异或,保持原值不变
? 与自身相异或,则全部位清零
? 交换两个整数值
?a=a^b; b=b^a; a=a^b;
C语言程序设计 - 第 9章 位运算 11
按位取反 (One's Complement)
? 运算规则
?~ 0 = 1;
?~ 1 = 0;
? 用法
?所有位翻转
?获得适用于不同系统的位运算模板
C语言程序设计 - 第 9章 位运算 12
按位取反举例
? 运算举例
~ 1010,1101 (0xAD)
0101,0010 (0x52)
? 位运算模板
?对一个 int类型的整数最后四位清零
16位整数,a & 0xF0
32位整数,a & 0xFFF0
可以使用,a & ~(int)0xF
C语言程序设计 - 第 9章 位运算 13
左移 (Left Shift)
? 运算规则
?i << n
?把 i各位全部向左移动 n位
?最左端的 n位被移出丢弃
?最右端的 n位用 0补齐
? 用法
?若没有溢出,则左移 n位相当于乘上 2n
?运算速度比真正的乘法和幂运算快得多
C语言程序设计 - 第 9章 位运算 14
左移举例
? 运算举例
1010,1101 << 3
(101)0110,1000_____
? 溢出举例
?若左移后的数据超出表示范围,则发生溢出
?int i,j;
i = 0x2431;
j = i<<2; /* j=-0x6F3C,溢出 */
j = i<<3; /* j= 0x2188,溢出 */
C语言程序设计 - 第 9章 位运算 15
右移 (Right Shift)
? 运算规则
?i >> n
?把 i各位全部向右移动 n位
?最右端的 n位被移出丢弃
?最左端的 n位用 0补齐 (逻辑右移 )
?或最左端的 n位用 符号位 补齐 (算术右移 )
? 用法
?右移 n位相当于除以 2n,并舍去小数部分
?运算速度比真正的除法和幂运算快得多
C语言程序设计 - 第 9章 位运算 16
右移举例
? 运算举例
0101,1101 >> 3
0000,1011(101)
? 逻辑右移和算术右移
?int i,j;
i=-0x2431;
j=i>>2; /* j=0x36F3,逻辑右移 */
j=i>>2; /* j=0xF6F3,算术右移 */
C语言程序设计 - 第 9章 位运算 17
不同长度数据位运算规则
? 两个操作数右端对齐
? 短的数据左端用符号位补齐
? 正数或无符号数左端用 0补满
? 负数左端用 1补满
? 两个操作数长度相等后再运算
C语言程序设计 - 第 9章 位运算 18
位运算举例
? 将 16进制短整数按二进制打印输出
输入,F1E2
输出,1111000111100010
输入,13A5
输出,0001001110100101
C语言程序设计 - 第 9章 位运算 19
例 1:将 16进制数按二进制输出
include <stdio.h>
void main()
{
int i;
short a;
scanf("%X",&a);
for (i=15;i>=0;i--)
printf("%1d",a&1<<i?1:0);
}
C语言程序设计 - 第 9章 位运算 20
结束
The End