位运算之 x & (-x)

位运算x&(-x)用于获取数字x的最低位1所对应的2的幂次方值。当x为0时结果为0,奇数时结果为1,偶数时结果为x中2的最大次方的因子,常被称为lowbit。此技巧可用于求解数字的最大2次方因子。

位运算之 x & (-x)


解释的太好了,我直接转载:

这里利用的负数的存储特性,负数是以补码存储的,对于整数运算 x&(-x)有

  • 当x为0时,即 0 & 0,结果为0;
  • 当x为奇数时,最后一个比特位为1,取反加1没有进位,故x和-x除最后一位外前面的位正好相反,按位与结果为0。结果为1。
  • 当x为偶数,且为2的m次方时,x的二进制表示中只有一位是1(从右往左的第m+1位),其右边有m位0,故x取反加1后,从右到左第有m个0,第m+1位及其左边全是1。这样,x&
    (-x) 得到的就是x。
  • 当x为偶数,却不为2的m次方的形式时,可以写作x= y * (2^k) 。其中,y的最低位为1。实际上就是把x用一个奇数左移k位来表示。这时,x的二进制表示最右边有k个0,从右往左第k+1位为1。当对x取反时,最右边的k位0变成1,第k+1位变为0;再加1,最右边的k位就又变成了0,第k+1位因为进位的关系变成了1。左边的位因为没有进位,正好和x原来对应的位上的值相反。二者按位与,得到:第k+1位上为1,左边右边都为0。结果为2^k。

总结:

x&(-x),当x为0时结果为0;x为奇数时,结果为1;x为偶数时,结果为x中2的最大次方的因子。

有一个专门的称呼,叫做 lowbit ,即取 2^k 。

甚至还可以进一步运用:求任意数字x的最大2次方因子。

那么当x为奇数的时候就为 (x-1) & ( -(x-1) ),当x为偶数的时候就为 x & (-x) 。

<think> 首先,用户的问题是:“我想查找x & -x运算的技巧 请问x & -x运算的技巧”。这是在询问关于位运算中 x & -x 的技巧。 我从系统级指令中知道: - 必须使用 $...$ 格式表示行内数学表达式。 - 独立公式用 $$...$$ 格式并单独成段。 - 使用中文回答。 - 生成相关问题。 - 在引用的段落末尾自然地添加引用标识,如 [^1]。 用户提供了几个引用: - 引用[1]:讨论了位运算技巧,包括获取二进制位中最低位的1的公式:lowbit(x) = x & -x。 - 引用[2]:提供了位运算的其他资源。 - 引用[3]:关于LeetCode位运算的例子。 - 引用[4]:关于定点数编程的注意事项。 用户的问题直接指向 x & -x 的技巧,引用[1] 中明确提到了这个技巧。所以,我应该基于引用[1] 来回答。 关键点来自引用[1]: - 位运算技巧--获取二进制位中最低位的1; - 公式:lowbit(x) = x & -x - 解释:如果x = (010010),则lowbit(x) = (000010)- 常用于数据结构树状数组中。 我还需要确保回答结构清晰,帮助用户逐步解决问题。 回答结构: 1. 介绍 x & -x 操作。 2. 解释其含义和用途。 3. 提供一个例子。 4. 引用相关信息。 5. 生成相关问题。 在回答中,自然地添加引用标识。例如,在解释时引用 [^1]。 数学表达式:当提到公式时,使用 $...$ 格式。例如,$x \& -x$。 独立公式:如果需要整体公式,用 $$...$$,但这里可能不需要单独的段落公式。 步骤: - 开头:确认用户的查询。 - 解释:x & -x 返回 x 的二进制表示中最低位的1的位置。 - 例子:例如,x = 10(二进制1010),则 x & -x = 2(二进制0010)。 - 用途:常用于树状数组(Fenwick Tree)等数据结构。 - 结尾:生成相关问题。 生成相关问题: - 根据主题,如位运算的其他技巧、应用场景等。 - 例如: 1. 如何使用 x & -x 实现树状数组? 2. 其他位运算技巧如判断奇偶性? 3. 位运算的性能优势? 确保中文回答。 最终响应: - 先回答问题。 - 然后添加“相关问题”部分。 </think> ### x & -x 运算的技巧 在计算机科学中,x & -x 是一种常见的位运算技巧,主要用于获取一个整数的二进制表示中最低位的1(即最右侧的1)。这个操作在算法设计中非常高效,尤其是在树状数组(Fenwick Tree)等数据结构中广泛应用[^1]。下面我将逐步解释其原理、用法和示例,确保回答清晰易懂。 #### 1. **运算原理** - x & -x 被称为 `lowbit` 函数,其数学定义为: $$\text{lowbit}(x) = x \& -x$$ 其中: - $x$ 是一个整数(通常为无符号整数或有符号整数的补码表示)。 - $-x$ 是 $x$ 的二进制补码(即所有位取反后加1)。 - 结果 $\text{lowbit}(x)$ 是一个整数,其二进制形式只保留 $x$ 中最低位的1,其他位均为0[^1]。 - 原理分析: - $-x$ 的二进制是 $x$ 的所有位取反(~x)再加1((~x) + 1)。 - 当 $x$ 和 $-x$ 进行按位与操作时,只有最低位的1会被保留,因为其他位在 $-x$ 中变为0或与原位不同。 - 例如,如果 $x$ 的二进制是 $(010010)_2$,则 $-x$ 是 $(101110)_2$(假设8位表示),两者相与得 $(000010)_2$。 #### 2. **主要用途** - **获取最低位的1**:快速提取 $x$ 二进制中最右侧的1的位置,常用于位操作优化。 - **树状数组(Fenwick Tree)**:在高效处理前缀和或区间查询时,$\text{lowbit}(x)$ 用于计算索引偏移量,提升算法性能[^1]。 - **判断2的幂次方**:通过 $\text{lowbit}(x) = x$ 可以快速判断 $x$ 是否为2的幂次方(例如 $x=8$ 时,$8 \& -8 = 8$)。 - **性能优势**:位运算基于硬件指令,时间复杂度仅为 $O(1)$,比常规算术操作更快[^2]。 #### 3. **示例演示** 假设 $x = 10$(二进制为 $(1010)_2$),计算 $x \& -x$: - 步骤分解: - $x$ 的二进制:$1010$ - $-x$ 的二进制(取反加1):$0110$(~10 = 0101, +1 = 0110) - 执行按位与:$1010 \& 0110 = 0010$ - 结果:$\text{lowbit}(10) = 2$(二进制 $(0010)_2$),对应最低位的1位于第二位。 - Python 代码验证: ```python def lowbit(x): return x & -x print(lowbit(10)) # 输出: 2 print(bin(lowbit(10))) # 输出: '0b10' (二进制表示) ``` 此代码显示了如何在实际编程中实现 $x \& -x$[^2]。 #### 4. **注意事项** - **整数范围**:当 $x$ 为负数时,需确保使用补码表示(现代计算机语言自动处理)。如果 $x = 0$,则结果为0,因为没有1可提取。 - **优化应用**:在树状数组中,$\text{lowbit}(x)$ 用于高效迭代索引,例如在求和查询中跳过中间步骤[^1]。 - 更多细节可参考位运算技巧资源[^2]。 此技巧简洁高效,是位运算中的基础工具,掌握了它能显著提升算法设计能力[^1]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值