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

关于Fenwick树(BIT)索引计算的C++版本兼容性问题

Fenwick树(BIT) read函数的位运算实现问题解析

问题1:C++20之前,idx[i+1] = idx[i] - (idx[i] & -idx[i]);是否属于不正确的实现?

是。C20之前的标准没有强制有符号整数采用补码表示,原码、反码都是合法的实现方式。这段代码的核心逻辑完全依赖补码下“负数等于按位取反加1”的特性,才能让idx[i] & -idx[i]提取出当前值的最低有效非零位掩码。如果编译器用非补码的有符号整数表示(比如原码),-idx[i]的位模式会完全偏离预期,&运算的结果无法得到正确掩码,最终导致read函数生成的索引序列错误。所以这段代码在C20之前属于不可移植的不正确实现,只能在默认用补码的编译器上侥幸运行。

问题2:C++20标准下,上述代码是否为正确实现?

是。C++20强制所有有符号整数类型必须使用补码表示,此时-idx[i]的位模式严格等于~idx[i] + 1,idx[i] & -idx[i]必然能精准提取当前值的最低有效非零位掩码。以示例中的idx=13(二进制00001101)为例:

  • 13 & -13等价于00001101 & 11110011(补码下-13的位模式),结果是00000001,13-1=12,符合要求;
  • 12的二进制是00001100,12 & -12是00001100 & 11110100,结果是00000100,12-4=8,完全匹配预期的索引序列。
    因此这段代码在C++20下是完全正确的实现。

问题3:无符号类型下,是否可使用idx[i+1] = idx[i] - (((~idx[i]) + 1) & idx[i])?

可以,但没必要写这么冗余。无符号整数的位运算在C++所有版本中都定义明确,~idx[i] + 1等价于无符号语义下的-idx[i](无符号减法是模2^N运算,-x的结果就是UINT_MAX - x + 1,和按位取反加1完全一致)。所以((~idx[i]) + 1) & idx[i]和idx[i] & -idx[i]的结果完全相同,直接写idx[i] - (idx[i] & -idx[i])在无符号类型下既简洁又正确,效果和长写法完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:20:23