
C语言基础之位运算(一)
C语言基础之位运算(二)
C语言基础之位运算(三)
内存存储的基本单位
1 和 0是计算机存储的基本单元,在计算机设备中看到的所有一切都是1和0两个数组成的,一个即一个位,即二进制中的一个数位,8位(bit)一个字节;反过来说,就是1字节是8位的数据,可以表示0-255共256个数字,即1Byte(字节) = 8Bit(位)。
拓展:
十六进制、二进制、字节等三者之间的关系
1个十六进制数位对应4个二进制数位(即2^4);2个十六进制数位对应8个二进制数位(即2^8);即1个字节。
1个字节=(2 * 1)个十六进制数位=(2 * 4)个二进制数位。
🌰例子:
0xFF = 1111 1111;
oxF = 1111 = 8+4+2+1 = 15;// 一个十六进制数位 = 4个二进制数位;4个二进制数最大表示为15;
例题:十六进制0xF6 转 二进制
F = 1111
6 = 0110
0xF6 = 1111 0110
解析:把十六进制中每个位数上的数单独转换成一个4位的二进制数,再做拼接。
1、按位与 &
1.1、描述:
-
位与时,两个操作数是按二进制位彼此对应位相与; - 若同为 1 则结果为 1;否则结果为 0;
1.2、真值表:
- 1&1=1;1&0=0;0&1=0;0&0=0;
1.3、特点:
- 与1位与无变化;与0位与变为0;
- 清零,任何数和0相与,结果为0;
- 若要取出指定位的值,取哪一位,就把对应的位定为1;
1.4、举例:
- 对于16位二进制数据data = 0000 1010 1110 0111;如何取出result数据的低4位 ?
// 0x000f = 0000 0000 0000 1111
// 通过按位与上data后,得到result = 0000 0000 0000 0111,就得到低4位数据0111;
int result = data & 0x000f;
2、按位或 |
2.1、描述:
-
位或时,两个操作数是按二进制位彼此对应位相或; - 只要有一个为 1 则结果为 1;否则结果为 0;
- 负数按补码的形式参加按位或运算;
2.2、真值表:
- 1 | 1=1;1 | 0=1;0 | 1=1;0 | 0=0;
2.3、特点:
- 与1位或变成1,与0位或无变化;
- 将数据的某些位,置为1;
2.4、举例:
- 2.4.1、计算10进制数据2和3的按位或
2 | 3 // 十进制
0000 0010 // 2 的二进制
0000 0011 // 3 的二进制
0000 0011 // 按位或的二进制结果,所以转为10进制就是3
- 2.4.2、将data = 1111 0000的低4位置为1
1111 0000
0000 1111
1111 1111 // 低4位置位1的结果
3、按位取反 ~
3.1、描述:
- 将操作数的二进制位逐个
取反; - 即0变1,1变0;
3.2、特点:
- 配合按
位与把一个数的指定位设置为0
3.3、举例:
- 3.3.1、对10进制数2位取反,即~2
data = 0000 0010
result = 111 1101 // 位取反后的结果
- 3.3.2、将data = 1000 1111按位与(~1)
1000 1111 // data
1111 1110 // ~1 即 ~(0000 0001)
1000 1110 // result = data & ~(1),此时data最低一位置为了0
4、按位异或 ^
4.1、描述:
- 若对应的位不同则为1;对应位相同则为0;
- 即异或就是
相异为1,相同则为0;
4.2、真值表:
- 1^1=0; 0^0=0; 1^0=1; 0^1=1;
4.3、特点:
- 特定位翻转,哪一位需要翻转就把对应的位设置为1;
- 任何值和0异或,原值保持不变;
- 异或运算可以交换位置;如:1^2^3 == 2^1^3
- 相同的数异或等于0:1^1==0; a^b^a ==b;
4.4、举例:
- 计算10进制数2^3的结果
2 ^ 3
0000 0010
0000 0011
0000 0001 // 2 ^ 3的结果为1
5、左移运算 <<
5.1、描述:
- 二进制位全部
左移若干位,左边的丢弃,右边的补0(无符号数据类型);
5.2、特点:
- 若左移时,舍弃的最高位不包含1时,则每左移一位,就乘以一次2;
- 所以a <<n的结果就是a乘以2的n次方;(a << n) == a * 2n;
5.3、举例:
- 将十进制3按位左移2,即3<<2, 求结果。
0000 0011 // 3
0000 1100 // 12 == 3按位左移2
6、右移运算 >>
6.1、描述:
- 二进制位全部
右移若干位,右边的丢弃,左边的补0(无符号数据类型); - 注意:对于
有符号的数据类型,当值为正数时,右边的丢弃,左边的补0;当值为负数时,右边的丢弃,左边的补1;
6.2、特点:
- 若右移时,舍弃的最高位不包含1时,则每右移一位,就除以一次2;
- 所以a>>n的结果就是a除以2的n次方;(a >> n) == a / 2n;
6.3、举例:
- 对于16位二进制数据data = 0000 1010 1110 0111;如何取出result数据的第5-8位?
// 0x00f0 = 0000 0000 1111 0000, 将data和0x00f0按位与,结果result = 0000 0000 1110 0000
// 然后像右移4位 ,得到最终所需要的数据result_number = 0000 0000 0000 1110
int result_number = (data & 0x00f0) >> 4;