1 << n 是 点亮第 n 位 这个是bit 位移 这个我懂 value << n 是 把数塞进第 n 位 这个不太明白啊

50 阅读2分钟

太好了,你这个问题问在点子上了
你已经懂 70% 了,现在卡的是那 30% 的“直觉层”
我这次不讲抽象概念,只用 「盒子 + 灯」 来把你这一下彻底掰直。


一句话先给你吃颗定心丸

value << n 不是“点亮一位”
它是:把一个「小数值」整体搬到某一段 bit 里


一、先建立一个“物理直觉”(很关键)

把 16 bit 想成 16 个小盒子

bit:  15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0
      ──────────   ─────────   ───────   ───────
       RIGHTLEFT区     BOTTOM区   TOP区

每一组 4 个盒子,不是用来“亮灯”
而是用来 放一个 0–15 的数字


二、1 << n:你已经完全懂了

1 << 6

意思是:

0000 0000 0100 0000
          
         6 位亮了

✔ 它只能表达 “有没有”
✘ 它不能表达 “是几”


三、关键来了:value << n 到底在干嘛?

举一个你现在正在用的真实例子

BOTTOM = 4;
bottomIndex = 5; // 0~5 的选项

第一步:先看 value 本身

bottomIndex = 5
// 二进制:
0101

这不是一个 bit,这是 一个“4 bit 的数”


第二步:value << 4 在做什么?

5 << 4

等价于:

原始 5:      0000 0000 0000 0101
左移 4 位:   0000 0000 0101 0000
                     ↑↑↑↑
                  塞进 bit 4~7

💥 这一步是关键理解点:

不是点亮一个灯
而是把 0101 这一整坨,
搬到 bit4~7 这 4 个盒子里


四、对比一下你为什么会被搞晕

❌ 错误的心理模型(大多数人都会掉坑)

1 << (BOTTOM + bottomIndex)

你潜意识以为:

“我存了 bottomIndex”

但实际上你干的是:

“点亮了某一盏灯”


✅ 正确模型

bottomIndex << BOTTOM

你说的是:

“我把 bottomIndex 这个数
放进 bottom 这 4 个 bit 的格子里”


五、为什么 value << n 能反推,而 1 << n 不行?

因为信息量不一样

写法盒子里内容能反推吗
1 << 60001
5 << 40101

六、反推的时候发生了什么?(你刚才卡的地方)

let bottom = (state >> 4) & 0b1111;

拆解含义

1️⃣ state >> 4
👉 把 bottom 区搬回最低位

2️⃣ & 0b1111
👉 只取这 4 个 bit

你拿回来的就是:

0101    5

七、一句终极口诀(背这个)

1 << n 是“点灯”
value << n 是“搬箱子”

或者更工程一点的:

bit flag 用 1
bit field 用 value


八、你现在其实已经会用了(只是差个确认)

你写这个:

let state =
  (topIndex    << 0)  |
  (bottomIndex << 4)  |
  (leftIndex   << 8)  |
  (rightIndex  << 12);

这是 100% 正确的协议写法
和 BLE / Zigbee / 米家 / Modbus 是同一套路。