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

基于long long的Bitmasking实现为何出现额外位错误?

位掩码集合实现的溢出问题排查

我在学习位掩码(Bitmasking)时,需要实现一个O(1)复杂度的集合数据结构,用于存储1<n<64的数字。但运行代码后,插入1、3、5、60并打印时,出现了28、33等额外数字;删除5后仍存在错误位,而非预期的1、3、60,请问这是为什么?

问题代码

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef vector<int> vi;


class BitMask
{

public:
    ll n;
    BitMask()
    {
        //call the class as Bitmask varname;
        n = 0;
    }
    void insert(long long x) {
        n |= (1 << x);
    }
    void deleteItem(long long x) {
        if (n & (1 << x)) {
            n &= ~(1 << x);
        }
    }
    void print() {
        for (int i = 0; i < 64; i++) {
            if (n & (1 << i)) {
                cout << i << endl;
            }
        }
    }

};

//implementation
int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    BitMask obj1;
    //insertion

    obj1.insert(1);
    obj1.insert(5);
    obj1.insert(3);
    obj1.insert(60);


    //print
    obj1.print();
    cout << endl;
    //deletion
    obj1.deleteItem(5);

    obj1.print();
    cout << endl;
    return 0;
}

问题原因

核心问题是整数溢出导致的未定义行为:

  • 代码中1 << x里的1是默认的32位int类型,而32位int的有效移位范围是0~31。当x≥32时,左移操作会触发溢出,生成的二进制值完全错误,直接污染了64位的位掩码变量n,导致出现28、33这类无关位被错误置1的情况。
  • 删除操作同理,1 << x溢出后无法正确定位目标位,要么删不掉指定值,要么误操作其他位。

修复方案

将移位操作的基数改为64位长整型,确保移位在合法范围内进行:
修改insert和deleteItem方法中的1 << x为1LL << x(1LL是64位长整型常量),这样左移60位不会溢出,能正确生成对应位的掩码。

修复后的关键代码:

void insert(long long x) {
    n |= (1LL << x);
}
void deleteItem(long long x) {
    if (n & (1LL << x)) {
        n &= ~(1LL << x);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:55:17