C++中为何x & (-x)等于能整除x的最大2的幂?
关于有符号整数按位与的困惑解答
嘿,我完全懂你的困惑——一开始确实很容易误以为有符号整数的正负版本只是符号位不同,但实际上计算机里的有符号负数是用补码表示的,这才是问题的核心!
咱们一步步拆解这个问题:
1. 先搞懂计算机怎么存有符号负数
计算机不会用“符号位翻转”的原码来存储负数(原码没法直接做加减法),而是用补码:
- 正数的补码和原码完全一样;
- 负数的补码 = 对应正数的反码(每一位0变1、1变0) + 1。
2. 拿12和-12的32位补码举例
先看正数12的32位二进制:
00000000 00000000 00000000 00001100
再算-12的补码:
- 先取12的反码:
11111111 11111111 11111111 11110011 - 再加1得到补码:
11111111 11111111 11111111 11110100
3. 计算12 & -12的结果
按位与的规则是:对应位都为1时结果才是1,否则是0。把两个补码对齐计算:
00000000 00000000 00000000 00001100 & 11111111 11111111 11111111 11110100 = 00000000 00000000 00000000 00000100
结果是二进制的100,也就是十进制的4——显然不是你预期的12。
4. 为什么要这么设计?
补码的最大优势是让加减法可以统一处理,不用区分正负。比如12 + (-12)用补码计算的话:
00000000 00000000 00000000 00001100 + 11111111 11111111 11111111 11110100 = 100000000 00000000 00000000 00000000
溢出的高位会被舍弃,最终结果就是0,完美符合数学预期。
总结一下:你的误区在于把原码的逻辑套到了实际存储的补码上,记住有符号负数在计算机中是补码形式,不是简单的符号位翻转,这就能理解为什么12 & -12不等于12啦。
内容的提问来源于stack exchange,提问作者Filip Kowalski
相关产品推荐
相关产品推荐

