美文网首页
二进制的经典应用-标志位与掩码

二进制的经典应用-标志位与掩码

作者: IvanRunning | 来源:发表于2020-04-29 13:28 被阅读0次

位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。虽然可以使用变量代替标志位序列,但是这样可以节省内存(1/32)。

例如有4个标志位:

1.标志位A: 我们有 orange
2.标志位B: 我们有 apple
3.标志位C: 我们有 banana
4.标志位D: 我们有 pear

标志位通过位序列DCBA来表示,当一个位置被置为1时,表示有该项,置为0时,表示没有该项。例如一个变量flag=9,二进制表示为1001,就表示我们有D和A。

掩码 (bitmask) 是一个通过与/或来读取标志位的位序列。典型的定义每个标志位的原语掩码如下:

var FLAG_A = 1; // 0001
var FLAG_B = 2; // 0010
var FLAG_C = 4; // 0100
var FLAG_D = 8; // 1000

新的掩码可以在以上掩码上使用逻辑运算创建。例如,掩码 1011 可以通过 FLAG_A、FLAG_B 和 FLAG_D 逻辑或得到:

var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011

某个特定的位可以通过与掩码做逻辑与运算得到,通过与掩码的与运算可以去掉无关的位,得到特定的位。例如,掩码 0100 可以用来检查标志位 C 是否被置位:(核心就是判断某位上的数

// 如果我们有 banana
if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
   // do stuff
}

一个有多个位被置位的掩码表达任一/或者的含义。例如,以下两个表达是等价的:

// 如果我们有 apple 或者 banana 至少一个
// (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
if ((flags & FLAG_B) || (flags & FLAG_C)) {
   // do stuff
}

var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
if (flags & mask) { // 0101 & 0110 => 0100 => true
   // do stuff
}

可以通过与掩码做或运算设置标志位,掩码中为 1 的位可以设置对应的位。例如掩码 1100 可用来设置位 C 和 D:(核心就是将某位变为1

// 我们有 banana 和 pear
var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
flags |= mask;   // 0101 | 1100 => 1101

可以通过与掩码做与运算清除标志位,掩码中为 0 的位可以设置对应的位。掩码可以通过对原语掩码做非运算得到。例如,掩码 1010 可以用来清除标志位 A 和 C :(核心就是将某位变为0

// 我们没有 orange 也没有 banana
var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
flags &= mask;   // 1101 & 1010 => 1000

如上的掩码同样可以通过 ~FLAG_A & ~FLAG_C 得到(德摩根定律):

// 我们没有 orange 也没有 banana
var mask = ~FLAG_A & ~FLAG_C;
flags &= mask;   // 1101 & 1010 => 1000

标志位可以使用异或运算切换。所有值为 1 的为可以切换对应的位。例如,掩码 0110 可以用来切换标志位 B 和 C:(核心就是将某位取反

// 如果我们以前没有 apple ,那么我们现在有 apple
// 但是如果我们已经有了一个,那么现在没有了
// 对 banana 也是相同的情况
var mask = FLAG_B | FLAG_C;
flags = flags ^ mask;   // 1100 ^ 0110 => 1010

最后,所有标志位可以通过非运算翻转:

// entering parallel universe...
flags = ~flags;    // ~1010 => 0101

建议扩展阅读
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
https://www.cnblogs.com/mopagunda/p/11221928.html

相关文章

  • 二进制的经典应用-标志位与掩码

    位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。虽然可以使用变量代替标志位序列,但是这样可以...

  • 子网划分及子网掩码计算方法

    子网划分及子网掩码计算方法 一、子网掩码的概述及作用 子网掩码是一个应用于TCP/IP网络的32位二进制值,每节8...

  • 子网划分及子网掩码计算方法

    一、子网掩码的概述及作用 子网掩码是一个应用于TCP/IP网络的32位二进制值,每节8位,必须结合IP地址对应使用...

  • 子网划分及子网掩码计算方式

    概述 1.子网掩码是一个应用于Tcp/Ip网络的32位二进制值,每节8位,必须结合IP地址对应使用。 2.子网掩码...

  • 网络层-子网掩码与子网划分

    一、子网掩码的概念及作用 子网掩码是一个应用于TCP/IP网络的32位二进制值,它可以屏蔽掉ip地址中的一部分,从...

  • 子网掩码(Subnet Mask)

    首先什么掩码?它的作用是什么? 掩码(Musk),在计算机科学和数字逻辑中,它指的是一串二进制数字。 掩码通过与目...

  • Bitmask在Rails中的应用

    Bitmask bitmask(位掩码),是利用二进制位,表示多种状态的组合,例如:4个状态的数据,有16种组合,...

  • 位掩码(Bit Mask)的应用

    刚开始做java,本文的也是以一个小白的角度,所以不足之处还请谅解。 书归正传,先说下背景,项目中需要添加一个功能...

  • [SceneKit]Intermediate Collision

    bit masks位掩码 就是一串二进制数据, 每个位表示特定的数值,并从最低有效位到最高有效位反向读取。如果该位...

  • Java/Kotlin 获取同子网所有 IP

    Kotlin Java 通过掩码位计算子网掩码 掩: 掩盖, 表示你不必关注的东西. 码: 编码, 二进制. ...

网友评论

      本文标题:二进制的经典应用-标志位与掩码

      本文链接:https://www.haomeiwen.com/subject/mbrgwhtx.html