文章

滴水-day19-位运算-掩码

位运算

sar 算数右移,不改变符号位.,最高位补符号位

sal 算数左移 最高位进CF,低位补0

sol 循环逻辑左移 高位移动给CF再移动到低位

sor 循环逻辑右移 低位移动到CF再移动到高位

rcl 带进位循环左移 高位移动给CF,CF移动给低位。

rcr 带进位循环右移 低位移动给CF,CF移动给高位。CF的移动是移位之前的值。

在C语言中~是非,!是取反。

shl 逻辑左移 最高位补0

shr 逻辑右移 最高位补0

0111 0000 >> 4 0000 0111 & F

0000 0111 & 1111 1111 == 0000 0111

1010 0101 >> 4 0000 1010 & 2 0000 0010

0000 1010 & 1111 1111 == 0000 1010

想要把某个位改为1,通过掩码和左移可以操作

1 << n 位, n从0开始,意思是把n+1位设置为1,再通过按位或即可把指定的位修改为1;

例如:要把 0111 的第四位改为1

0111 (1 << 3) 0001 << 3 ---> 1000 | 0111 1111

想要清除某个位,可以使用非和按为与操作

还是同样的理解:

对于想要清除的位,构造一个掩码对其进行取非操作,这样1变成0,0变成1,

在进行按位与操作,这样就可以清除特定的位。

例如这里要把第四位改为0,那么就构造一个第四位是0其余三位全是1的数

高位是0其余是1,可以通过取非,先确定需要清除的位,使得 1 左移 位数-1 再取非,就可以得到这样一个数。

在进行按位与即可把特定的位清除。

1111 1 << 3 = 1000 ~ 0111 & 1111 == 0111

翻转特定位的值

想要把特定位的1改为0,或0改为1.

通过异或操作可以完成

比如:1111

把第2位翻转

1 << 1 --> 0001 0010 ^ 1111 == 1101

在对特定的位进行读或写的时候要使用使用重要的概念:

掩码

GPT解释

掩码(mask)在位运算中是一种用于选择和操作特定位的工具。掩码的作用是通过按位与操作(&)或按位或操作(|)来保留或修改数据的特定位,而不影响其他位。以下是掩码的作用和原理:

掩码的作用

  1. 提取特定位: 使用掩码可以提取数据中的特定位值。例如,提取数据的低4位,或某些特定位置的位。

  2. 设置特定位: 通过按位或操作和适当的掩码,可以将数据中的某些位设置为1。

  3. 清除特定位: 通过按位与操作和适当的掩码,可以将数据中的某些位清零。

  4. 切换特定位: 通过按位异或操作和掩码,可以切换(翻转)数据中的特定位。

掩码的原理

掩码通常是一个二进制数,其中1表示要操作的位,0表示不操作的位。不同的操作可以通过不同的位运算符来实现。

1. 提取特定位(按位与操作)

  • 原理: 使用掩码和数据进行按位与操作,仅保留掩码中为1的位的对应位。

  • 例子: 提取低4位

  • 数据: data = 0xA5(1010 0101)

  • 掩码: mask = 0x0F(0000 1111)

  • 操作: data & mask = 1010 0101 & 0000 1111 = 0000 0101

  • 结果: 0x05(5)

2. 设置特定位(按位或操作)

  • 原理: 使用掩码和数据进行按位或操作,将掩码中为1的位的对应位设置为1。

  • 例子: 设置低4位为1

  • 数据: data = 0xA5(1010 0101)

  • 掩码: mask = 0x0F(0000 1111)

  • 操作: data | mask = 1010 0101 | 0000 1111 = 1010 1111

  • 结果: 0xAF(175)

3. 清除特定位(按位与操作与掩码取反)

  • 原理: 使用掩码取反后和数据进行按位与操作,将掩码中为1的位的对应位清零。

  • 例子: 清除低4位

  • 数据: data = 0xA5(1010 0101)

  • 掩码: mask = 0xF0(1111 0000)

  • 操作: data & ~mask = 1010 0101 & 1111 0000 = 1010 0000

  • 结果: 0xA0(160)

4. 切换特定位(按位异或操作)

  • 原理: 使用掩码和数据进行按位异或操作,掩码中为1的位的对应位将被翻转。

  • 例子: 切换低4位

  • 数据: data = 0xA5(1010 0101)

  • 掩码: mask = 0x0F(0000 1111)

  • 操作: data ^ mask = 1010 0101 ^ 0000 1111 = 1010 1010

  • 结果: 0xAA(170)

License:  CC BY 4.0