叙述:
嵌入式位运算是嵌入式系统中常用的优化技巧之一,它可以通过位运算操作来实现一些常见的数学运算、逻辑运算等,从而提高程序的执行效率。
本文就这方面进行介绍。
我个人认为,位操作就是取、删、反、移位、清空、切换等这些,但是在实际中因为对这方面的理解不够透彻,导致在写代码时,不知道怎么操作。
位移运算
位移运算包括左移运算和右移运算,通过将二进制数的位向左或向右移动指定的位数,可以实现快速的乘以或除以2的幂次方操作。例如,将一个整数向左移动3位,相当于将其乘以2的3次方(即8),将一个整数向右移动2位,相当于将其除以2的2次方(即4)。
1int x = 10; // 声明一个整数变量 x,初始值为 10 2int y = x << 3; // 将 x 左移 3 位,相当于乘以 8 3int z = x >> 2; // 将 x 右移 2 位,相当于除以 4
位与运算
位与运算是对两个数的每个二进制位进行逻辑与操作,如果两个相应的二进制位都为1,则该位的结果为1,否则为0。位与运算常用于掩码操作、判断奇偶性等。
1int x = 0x0F; // 声明一个整数变量 x,初始值为 0x0F(二进制为 0000 1111) 2int y = 0x03; // 声明一个整数变量 y,初始值为 0x03(二进制为 0000 0011) 3int z = x & y; // 对 x 和 y 进行位与运算,结果为 0000 0011(十进制为 3)
位或运算
位或运算是对两个数的每个二进制位进行逻辑或操作,如果两个相应的二进制位中至少有一个为1,则该位的结果为1,否则为0。位或运算常用于设置标志位、合并掩码等。
1int x = 0x0F; // 声明一个整数变量 x,初始值为 0x0F(二进制为 0000 1111) 2int y = 0x03; // 声明一个整数变量 y,初始值为 0x03(二进制为 0000 0011) 3int z = x | y; // 对 x 和 y 进行位或运算,结果为 0000 1111(十进制为 15)
位异或运算
位异或运算是对两个数的每个二进制位进行逻辑异或操作,如果两个相应的二进制位不相同,则该位的结果为1,否则为0。位异或运算常用于取反标志位、差分数据传输等。
1int x = 0x0F; // 声明一个整数变量 x,初始值为 0x0F(二进制为 0000 1111) 2int y = 0x03; // 声明一个整数变量 y,初始值为 0x03(二进制为 0000 0011) 3int z = x ^ y; // 对 x 和 y 进行位异或运算,结果为 0000 1100(十进制为 12)
位取反运算
位取反运算是对一个数的每个二进制位进行逻辑取反操作,即将1变为0,0变为1。位取反运算常用于反转标志位、取反掩码等。
1int x = 0x0F; // 声明一个整数变量 x,初始值为 0x0F(二进制为 0000 1111) 2int y = ~x; // 对 x 进行位取反运算,结果为 1111 0000(十进制为 -16)
位域操作
位域是一种将一个或多个字段打包到一个单一的机器字中的数据结构。位域可以有效地压缩存储空间,并且可以提高程序的执行效率。位域常用于控制寄存器、状态寄存器等。
1struct { 2 unsigned char a : 4; // 定义一个 4 位的无符号整数字段 a 3 unsigned char b : 3; // 定义一个 3 位的无符号整数字段 b 4 unsigned char c : 1; // 定义一个 1 位的无符号整数字段 c 5} bitfield; 6 7bitfield.a = 5; // 设置字段 a 的值为 5(二进制为 0101) 8bitfield.b = 2; // 设置字段 b 的值为 2(二进制为 010) 9bitfield.c = 1; // 设置字段 c 的值为 1(二进制为 1)
清除位:
可以使用位运算符将特定的位设置为0。例如,如果需要清除一个8位字节的最高位,可以使用以下代码:
1unsigned char byte = 0xFF; 2byte &= 0x7F; // Clear the highest bit
设置位:
可以使用位运算符将特定的位设置为1。例如,如果需要将一个8位字节的第4位设置为1,可以使用以下代码:
1unsigned char byte = 0x00; 2byte |= 0x10; // Set the 4th bit
反转位:
可以使用位运算符将特定的位取反。例如,如果需要反转一个8位字节的所有位,可以使用以下代码:
1unsigned char byte = 0x55; 2byte ^= 0xFF; // Invert all bits
检查位:
可以使用位运算符检查特定的位是否设置为1或0。例如,如果需要检查一个8位字节的第2位是否为1,可以使用以下代码:
1unsigned char byte = 0x04; 2if (byte & 0x02) { 3 // The 2nd bit is set 4} else { 5 // The 2nd bit is not set 6}