位运算工程速记教程(背这个就够)

37 阅读2分钟

好,这次我不“解释”,我给你一份可以直接背的「位运算·工程级速记教程」
你就当是口诀 + 模板,以后不再纠结、不再晕。


🧠 位运算工程速记教程(背这个就够)


一、先背这 3 句「生死线」

1 << n点亮第 n 位

✔ 表示「有没有」
✘ 不表示「是多少」


value << n把数塞进第 n 位

✔ 表示「这个字段的值」
✔ 一定能反推


③ 能反推值 ⇒ 不是 1 << n

反推不了 ⇒ 才是 1 << n


二、两大用法(死记)

🟢 用法一:位标志(one-hot)

用途

  • 权限
  • 开关
  • 状态

口诀

「有没有,用 1」

const READ  = 1 << 0;
const WRITE = 1 << 1;
const EXEC  = 1 << 2;

let state = READ | EXEC;

判断

if (state & READ) { }

永远不要反推“是第几个”


🔵 用法二:位段字段(value-field)【你现在用的】

用途

  • 枚举
  • 下标
  • 协议
  • 0–5 / 0–15 这种值

口诀

「是多少,用 value」

state |= value << offset;

三、你这个项目的「标准模板」(背这个)

1️⃣ 位段划分(16 bit)

TOP    = 0;   // bit 0~3
BOTTOM = 4;   // bit 4~7
LEFT   = 8;   // bit 8~11
RIGHT  = 12;  // bit 12~15

2️⃣ 打包(写值)

function pack(top, bottom, left, right) {
  return  (top    << TOP)
        | (bottom << BOTTOM)
        | (left   << LEFT)
        | (right  << RIGHT);
}

top / bottom / left / right0–15 的数字


3️⃣ 解包(反推)

function unpack(state) {
  return {
    top:    (state >> TOP)    & 0b1111,
    bottom: (state >> BOTTOM) & 0b1111,
    left:   (state >> LEFT)   & 0b1111,
    right:  (state >> RIGHT)  & 0b1111,
  };
}

4️⃣ 真实例子(你现在的)

const state = pack(
  0, // 上
  5, // 下
  0, // 左
  0  // 右
);

反推:

const { bottom } = unpack(state);
// bottom === 5

四、为什么你之前 (state >> 4) & 0xff 会懵

❌ 错误认知

1 << (4 + index)

你以为:

“我存了 index”

实际是:

“我点亮了某一位”


✅ 正确认知

index << 4

你说的是:

“我把 index 这个数,写进 bit4~7”


五、判断用哪种的「终极一问」

问自己一句话:

👉「我以后需不需要知道它是几?」

答案写法
需要value << n
不需要1 << n

六、你可以直接贴在项目里的注释(推荐)

/**
 * bit protocol:
 * bit 0~3   : top    (0~15)
 * bit 4~7   : bottom (0~15)
 * bit 8~11  : left   (0~15)
 * bit 12~15 : right  (0~15)
 *
 * use value << offset (NOT one-hot)
 */