公司动态
C++信奥位运算
♂️ C 魔法课位运算大冒险------彭彭老师各位小魔法师欢迎来到计算机的微观世界在这里所有的数字都是由0和1组成的。掌握“位运算”就像掌握了控制计算机的底层魔法不仅能让你的代码跑得飞快还能解开很多看似复杂的谜题第一章数字的“变身术” (原码、反码、补码)在计算机里正数和负数的存储方式是不一样的。我们要学会看穿它们的“伪装”。1. 机器数与真值真值就是我们平时看到的数比如5-5。机器数计算机里存的二进制数。最高位最左边是符号位0代表正1代表负。例子假设只有 8 位bit。5的机器数0000 0101-5的机器数1000 0101(这是原码)2. 三兄弟变身记计算机为了做减法方便发明了反码和补码。类型规则例子 (-5)记忆口诀原码符号位 绝对值的二进制1000 0101原封不动首位定正负反码正数不变负数符号位不变其余取反1111 1010负数除了首位0变11变0补码正数不变负数是反码 11111 1011反码加一计算机最爱用 重点提示在 C 代码里整数在内存中都是以补码形式存在的正数的 原码 反码 补码。负数一定要记得“取反加一”才是它在电脑里的真面目。原码、反码、补码是计算机中表示有符号整数的三种编码方式它们之间的转换规则非常清晰核心在于正数三码相同负数按“取反加一”规则转换。一、基本定义以8位二进制为例原码最高位为符号位0正1负其余位表示数值的绝对值。反码正数与原码相同负数符号位不变其余位按位取反。补码正数与原码相同负数是反码末位加1。✅ 重要前提计算机中所有整数运算都基于补码进行二、转换规则详解1. 正数三码完全相同例如58位原码0000 0101反码0000 0101补码0000 01012. 负数从原码 → 反码 → 补码以 -5 为例原码1000 0101符号位1数值位5的二进制反码1111 1010符号位不变其余位取反补码1111 1011反码 13. 从补码 → 原码逆向转换这是考试和调试中最常考的部分方法对补码再求一次补码即可得到原码。即补码 → 取反 → 加1 → 得到原码。仍以 -5 的补码1111 1011为例第一步取反 →0000 0100第二步加1 →0000 0101第三步加上符号位 →1000 0101即 -5 的原码 小技巧也可以直接“从右往左找第一个1这个1左边的所有位取反”快速得到原码。三、为什么需要补码统一加减法计算机只有加法器补码让减法变成加法如 A - B A (-B)。消除±0问题原码和反码都有 0 和 -0补码只有一个 00000 0000节省空间且避免歧义。扩展表示范围8位补码可表示 -128 ~ 127比原码多一个负数。二进制里为什么要出现原码 反码 补码核心原因是为了让计算机的加法器能统一处理加法和减法并彻底解决“0”和“-0”表示不唯一的问题。这三种编码本质上是计算机在“人类直觉”与“硬件效率”之间逐步优化的演进结果。原码最符合人类直觉原码就是“符号位 绝对值”最高位为符号位0正1负其余位表示数值大小。以 8 位二进制为例1 的原码0000 0001 -1 的原码1000 0001致命缺陷加减法不统一1 (-1)按原码直接相加会得到1000 0010即 -2结果完全错误。零的表示不唯一0为0000 0000-0为1000 0000浪费了一个编码位。反码试图解决加减法问题反码规定正数的反码与原码相同负数的反码是符号位不变其余位按位取反。1 的反码0000 0001 -1 的反码1111 1110改进与遗留缺陷加减法初步统一1 (-1)计算为0000 0001 1111 1110 1111 1111结果正是-0的反码逻辑上说得通。零的表示依然不唯一0为0000 0000-0为1111 1111问题仍未彻底解决。补码最终的完美方案补码规定正数的补码与原码相同负数的补码是其反码加 1。1 的补码0000 0001 -1 的补码1111 1111三大核心优势彻底解决零的表示1 (-1)计算为0000 0001 1111 1111 1 0000 0000丢弃最高位进位后结果为0000 0000唯一的 0。加减法完全统一减法可转化为加法A - B A (-B)CPU 只需设计一套加法电路无需额外设计减法器。多表示一个负数8 位二进制下原码和反码的表示范围均为-127 ~ 127而补码的表示范围为-128 ~ 127多出的1000 0000被用来表示-128。总结对比原码反码补码零的表示不唯一0 和 -0不唯一0 和 -0唯一加减法需要额外判断符号基本统一完全统一硬件复杂度高需减法器中低只需加法器表示范围8位-127 ~ 127-127 ~ 127-128 ~ 127简而言之原码是给人类看的补码是给机器用的反码则是从原码到补码的过渡方案。现代计算机底层统一采用补码正是因为它能用最简单的硬件电路实现最高效的运算。 题1写出 -7 的原码、反码、补码8位✅ 答案原码1000 0111反码1111 1000补码1111 1001 题2已知某数补码为1111 1100求其原码和十进制值。✅ 解答补码 → 取反 →0000 0011加1 →0000 0100加符号位 →1000 0100→ 原码十进制值-4 题3计算~(-1)的结果8位✅ 解答-1 的补码1111 1111按位取反0000 0000结果0对于正数来说原码、反码、补码长得一模一样所以根本不需要做任何转换。只有负数才需要“取反加一”这一套操作。为什么正数三码相同因为正数的符号位是0而反码和补码的规则都是“符号位不变其余位……”反码规则符号位不变其余位取反 → 正数其余位不取反所以和原码一样。补码规则反码 1 → 正数的反码就是原码再加 1 就不对了……等等这里有个细节要澄清正数的补码规则是正数的补码 原码而不是“反码 1”。也就是说补码的定义是正数补码 原码负数补码 反码 1所以正数从头到尾都不需要任何转换三码完全一致。一句话总结数的类型原码反码补码需要转换吗正数✅ 原码 原码不需要负数✅符号位不变其余取反反码 1需要零0000 00000000 00000000 0000不需要考试/做题时的快速判断拿到一个数先看符号位最高位是0→ 正数 → 三码相同直接抄。最高位是1→ 负数 → 才需要动脑筋转换。第二章六大元素魔法 (位运算符)位运算是直接对二进制位进行操作。想象一下你有两排开关0是关1是开我们要对它们进行控制。1. 按位与(AND) —— “严格考官”规则两位都是 1结果才是 1否则为 0。口诀全 1 则 1有 0 则 0。作用清零想让哪一位变 0就和 0 做与运算。取低位比如x 1可以判断奇偶结果是 1 就是奇数。2. 按位或|(OR) —— “宽容考官”规则只要有一个是 1结果就是 1两位都是 0 才是 0。口诀有 1 则 1全 0 则 0。作用置位想把某一位强行变成 1就和 1 做或运算。3. 按位异或^(XOR) —— “找不同大师”规则两位不同结果为 1相同结果为 0。口诀相同为 0不同为 1。神奇性质必考a ^ a 0(自己异或自己灰飞烟灭)a ^ 0 a(任何数异或 0还是它自己)交换律a ^ b ^ a b(可以用来不借助第三个变量交换两个数)4. 按位取反~(NOT) —— “颠倒黑白”规则单目运算符。0 变 11 变 0。注意~x等于-(x1)。比如~5是-6。5. 左移—— “翻倍加速器”规则把所有位向左移动 n 位右边补 0。数学意义相当于乘以2n2^n2n。1 3就是1×2381 \times 2^3 81×238(二进制1000)。用途快速构造 2 的幂次方或者把某个 1 移到指定位置。6. 右移—— “减半切割机”规则把所有位向右移动 n 位。对于正数左边补 0。对于负数左边通常补 1 (算术右移)。数学意义相当于除以2n2^n2n(向下取整)。8 2就是8/428 / 4 28/42。第三章谁大谁小(优先级)这是新手最容易踩坑的地方位运算的优先级比加减乘除低很多危险陷阱// 错误写法if(n10)...// 电脑会先算 10 (得0)再算 n0结果永远是0// 正确写法一定要加括号if((n1)0)...优先级顺口溜算术运算排第一* / % -移位运算排第二 关系运算排第三 位与位异排第四^|逻辑运算在最后||。记不住那就永远给位运算加上小括号()第四章实战演练场 (练习题)来试试身手吧 练习 1判断奇偶题目输入一个整数 n如果是奇数输出 “Odd”偶数输出 “Even”。要求使用位运算。思路看二进制的最后一位。最后一位是 1 就是奇数。代码片段if(n1)coutOdd;elsecoutEven; 练习 2神秘的交换题目有两个变量a3, b5不使用第三个变量t交换它们的值。思路利用异或的性质a ^ b ^ a b。代码片段aa^b;// 此时 a 存的是混合密码ba^b;// (a^b)^b - ab 变成了原来的 aaa^b;// (a^b)^a - ba 变成了原来的 b 练习 3消灭唯一的数 (经典题)题目一个数组里只有一个数字出现了 1 次其他数字都出现了 2 次。找出那个只出现 1 次的数字。思路利用a ^ a 0。把所有数字全部异或起来成对的都抵消变成 0 了剩下的就是那个单身狗代码片段intans0;for(inti0;in;i){ans^arr[i];}coutans; 总结位运算虽然看起来像天书但只要记住“0和1的游戏”多画图模拟几次你就会发现它比普通的加减法还要有趣光看不练假把式。 4 道题目从基础计算到逻辑推理难度循序渐进。建议拿出一张纸和一支笔先把二进制写下来再算哦 第一关基础热身口算题题目已知整数a 5b 3。请计算以下三个表达式的值结果写成十进制a b按位与a | b按位或a ^ b按位异或 提示先把 5 和 3 变成二进制比如0101和0011然后一位一位对齐来算。 第二关移形换位移位运算题目有一个整数x 4二进制是...0000 0100。执行x 2左移 2 位后x变成了多少执行x 1右移 1 位后x变成了多少 思考左移是不是相当于乘法右移是不是相当于除法试试看能不能发现规律 第三关神探夏洛克逻辑推理题目小明在写代码时不小心把两个变量搞混了。现在他手里有两个数A和B他想交换这两个数的值但是不允许使用第三个临时变量比如不能用int temp。请问利用我们学过的“按位异或^”魔法下面哪段代码能成功交换 A 和 B选项 1AA^B;BA^B;AA^B;选项 2AAB;BA|B;AA^B; 第四关BOSS 挑战负数陷阱题目这是一道易错题请计算-1在计算机里的补码表示假设是 8 位二进制然后对-1进行按位取反~操作。问~(-1)的结果是多少 提示先写出 1 的原码。再写出 -1 的补码取反加一。最后对 -1 的补码每一位都取反0变11变0。看看结果是什么是不是很神奇✅ 答案与解析做完再看哦第一关答案1解析01010011-0001(十进制 1)7解析0101|0011-0111(十进制 4217)6解析0101^0011-0110(相同为0不同为1十进制 426)第二关答案16解析4(100) 左移 2 位变成10000(十进制 16)。规律左移 n 位等于乘以2n2^n2n(4×22164 \times 2^2 164×2216)。2解析4(100) 右移 1 位变成10(十进制 2)。规律右移 n 位等于除以2n2^n2n(4/2124 / 2^1 24/212)。第三关答案选项 1 正确解析这是经典的“异或交换法”。第一步A A ^ B(A变成了混合体)第二步B (A ^ B) ^ B-A ^ (B ^ B)-A ^ 0-原来的 A(B 成功拿到了 A 的值)第三步A (A ^ B) ^ A(注意这里的B已经是原来的A了) -(A ^ B) ^ A-B ^ (A ^ A)-B ^ 0-原来的 B(A 成功拿到了 B 的值)第四关答案结果是 0解析1的原码0000 0001-1的补码先取反1111 1110再加 1 -1111 1111(全是1)~(-1)把1111 1111全部取反 -0000 0000。结论在计算机里~(-1)永远等于0。这是一个非常有用的性质