计算机基础学习:位运算(一)

67 阅读3分钟

文章内容主要为小册《程序员的必修课》的学习笔记以及个人理解,仅供个人学习使用。详细内容请支持正版小册

按位与(&):将各个数位的数字进行逻辑与,都是 1 才为 1,否则为 0

比如说某个游戏有 6 种职业:

  • 法师 0000 0001
  • 盗贼 0000 0011
  • 战士 0000 0111
  • 德鲁伊 0000 1111
  • 猎人 0001 1111
  • 治愈者 0011 1111

我们用一些二进制去维护这些职业,并用逻辑与进行判断

let mage = 0b00000001; // 法师 
let thief = 0b00000011; // 盗贼
let warrior = 0b00000111; // 战士
let druid = 0b00001111; // 德鲁伊 
let hunter = 0b00011111; // 猎人
let healer = 0b00111111; // 治愈者

// 是否是法师
function isMage(flag) {
    return (mage & flag) === mage;
}

// 是否是盗贼
function isThief(flag) {
    return (thief & flag) === thief;
}

// 是否是战士
function isWarrior(flag) {
    return (warrior & flag) === warrior;
}

// 是否是德鲁伊
function isDruid(flag) {
    return (druid & flag) === druid;
}

// 是否是猎人
function isHunter(flag) {
    return (hunter & flag) === hunter;
}

// 是否是治愈者
function isHealer(flag) {
    return (healer & flag) === healer;
}

我们会发现,像一些枚举、并列关系的对象,其实可以用二进制位掩码的形式去改写,并进行判断,这种方法既高效又便于处理状态组合。

按位或(|):将各个数位的数字进行逻辑或,只要有一个为 1 就是 1,都为 0 才是 0

比如 a = 1001,b = 0110,那么a | b = 1111

假设说现在小明要进行角色的选择,希望变成到盗贼,那么此时可以这么写

function beThief(originFlag) {
    return originFlag | thief
}

异或(^):将各个位置数字进行异或,相同为 0,不同为 1

它有一些特性,比如,一个数和 0 异或等于它本身。一个数和自身异或等于 0。

于是如果要判断某个数字是否为 0,可以有以下函数

function isZero(num) {
  return (666 ^ num) === 666 // 这里的 666 是随便写的,你可以换成 123
}

通过这个特性还可以做一些骚操作,比如常见的 swap 函数,一般是这样写:

let a = 1
let b = 2
let temp = a
a = b
b = temp

但是利用异或的特性,可以写成这样

a = a ^ b; // 此时 a 等于a ^ b
b = a ^ b; // 此时 b = (a ^ b) ^ b,由于b ^ b等于 0,所以 a ^ 0 等于 a,那么此时 b 就等于 aa = a ^ b; // 此时 a = a ^ (a ^ b),和上面的相似,由于a ^ a等于 0,所以 0 ^ b 等于 b,那么此时 a 等于 b

非运算(!)

这个太简单了,判断 false 的情况一般都会用到这个,可以理解为负负得正,非 false,那就是 true 了

if (xxx === false) {
    // todo...
}

// 等价于以下代码
if (!xxx) {
    // todo...
}