You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

位操作中[i,j]区间掩码生成公式~0<<j | ((1<<i)-1)原理咨询

拆解位掩码 ~0 << j | ((1 << i) - 1) 的原理

嘿,这个位操作的问题我当初刚学的时候也绕了半天,咱们一步步拆解清楚,结合你的代码来理解:

首先明确咱们的核心目标:要生成一个掩码,用它和N做按位与(&)后,能把N的[i,j]位段清零,同时保留其他所有位的原值。这个掩码的特点就是:[i,j]位是0,其他位是1。

第一步:拆分掩码的两个组成部分

假设我们用的是32位有符号整数(C语言里常见的情况),先看每一部分的作用:

1. ~0 << j

~0 在二进制里是所有位都为1的数(因为0的二进制全是0,取反后自然全1)。把它左移j位后:

  • 原来的最低j位会被挤出去,补成0;
  • 从第j位到最高位(31位)保持为1。
    比如j=5,32位下这个值是0xFFFFFFE0,二进制就是111...11100000(最后5位是0)。

2. (1 << i) - 1

1 << i 是把数字1左移i位,得到一个二进制里只有第i位是1、其余是0的数。再减1之后:

  • 第0位到第i-1位都会变成1;
  • 第i位到最高位保持为0。
    比如i=2,这个值是0x00000003,二进制就是000...00000011(最后2位是1)。

第二步:按位或(|)组合两个部分

按位或的规则是:只要对应位有一个是1,结果就是1。把上面两个部分组合起来:

  • 第一部分的高位(j位及以上)是1,第二部分的低位(i-1位及以下)是1;
  • 中间的i位到j-1位,两个部分都是0,所以组合后这一段还是0。

最终得到的掩码正好是我们需要的:[i,j]位段为0,其余位为1。

结合你的代码看完整流程

现在把这个逻辑套进你的代码里,就一目了然了:

void merge(int N, int M, int i, int j){
 int mask = ~0 << j | ((1 << i) - 1);
 N = N & mask; // 用掩码清掉N的[i,j]位,其他位保留
 mask = ~(mask); // 反转掩码:现在[i,j]位是1,其余位是0
 M = M & mask; // 用反转后的掩码只保留M的[i,j]位,其他位清零
 N = N | M; // 把M的[i,j]位合并到N的对应位置
}

举个8位的具体例子更直观:

  • 假设N=0b10101010,M=0b00110011,i=2,j=5
  • 第一步生成的掩码是0b11100011,N & mask后得到0b10100010(位2-5被清零)
  • 反转掩码得到0b00011100,M & mask后得到0b00010000(只保留M的位2-5)
  • 最后N | M得到0b10110010,完美完成合并!

内容的提问来源于stack exchange,提问作者Ebb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:18:35