)
软考软件设计师上午题里数据表示这块每年稳定送 2~3 分原码反码补码移码的转换、表示范围、溢出判断翻来覆去就这几个考点。但很多同学这块总是学了忘、忘了学原因只有一个直接背结论没理解为什么这么设计。这篇文章换个讲法——先讲清楚为什么要发明这些码结论你自己就能推出来根本不用背。文章最后附 10 道真题级练习前 5 道基础题后 5 道全是软考爱挖的坑答案和详解放在最后建议先做完再对答案。一、为什么会有四种码一个减法问题计算机要表示负数最直觉的方案是最高位当符号位0 正 1 负剩下的位放绝对值。这就是原码。比如 8 位字长下45 原码00101101 45 32841 -45 原码10101101 只是符号位从 0 变 1看起来很美但硬件工程师很快发现一个致命问题原码做加减法太麻烦了。计算5 (-3)加法器得先比较两个绝对值谁大、决定到底做加法还是减法、再根据规则定结果符号……一套流程下来电路极其啰嗦。工程师想要的是减法能不能直接变成加法一套加法器走天下于是有了反码负数按位取反过渡产物最终定型为补码反码 1。补码的妙处减法变加法符号位直接参与运算结果自动正确而且 0 只有一种表示。今天全世界计算机的整数运算用的都是补码。至于移码是另一条线上的需求——它不为运算专为比大小服务第四部分单独讲。二、四种码的定义一个例子算到底以-45为例8 位字长手把手走一遍四种码原码10101101 ↓ 符号位不变数值位按位取反0变11变0 反码11010010 ↓ 在最低位 1 补码11010011 ↓ 符号位取反其余位不动 移码01010011三条规则背下来正数的原码、反码、补码完全相同45 三种码都是00101101上面这套变换只对负数有意义负数的补码 反码 1移码和补码只差一个符号位其余位一模一样。反向操作给补码求真值补码的补码就是原码所以数值位取反再加 1原路走回去即可。比如补码11010011数值位1010011取反得0101100加 1 得0101101 45加上符号 →-45。✓ 和出发时一致。三、核心区别一表示范围每年必考8 位字长1 位符号、7 位数值绝对值最大1111111 127。那范围到底是 -127 还是 -128关键看 0 占几个编码码制0-00 的表示定点整数范围原码0000000010000000不唯一-127 127反码0000000011111111不唯一-127 127补码00000000不存在唯一-128 127原码和反码里 0 占了两个编码浪费了一个只能表示 255 个数。补码里 0 唯一省下来的10000000被规定为-128——所以补码负数比正数多一个。n 位字长的通用公式直接背补码/移码-2ⁿ⁻¹ 2ⁿ⁻¹-1 原码/反码-(2ⁿ⁻¹-1) (2ⁿ⁻¹-1)特例警告-128 的补码10000000没有对应的原码8 位放不下 128走不了原码→反码→补码的流程它是直接规定的。这是后5题里第一个坑。四、移码专为比大小而生移码的定义真值 2ⁿ⁻¹8 位即 128结果按无符号数理解。验证一下-45 的移码 -45 128 83 01010011和第二部分补码翻符号位的结果一致。这就是为什么移码 补码符号位取反不是巧合是定义使然。浮点数的阶码为什么用移码因为移码有保序性真值越大机器数按无符号数读越大。比如 -45 的移码是 835 的移码是 133——机器数大小和真值大小完全同向。比较两个阶码谁大比较器当普通无符号数一比就完事硬件最省事。换成补码就拧巴了-1 的补码11111111比 1 的00000001机器数还大比较前还得先解释符号。五、补码运算与溢出判断补码最得意的本领减法变加法。算5 - 3实际是5 (-3)00000101 (5) 11111101 (-3 的补码) ---------- 100000010 → 最高位第9位进位丢弃 00000010 2 ✓但 8 位补码只能装 -128 ~ 127两个大数相加会装不下这就是溢出。比如 70 7001000110 (70) 01000110 (70) ---------- 10001100 → 读作补码 -116两个正数相加得负数显然错了溢出判断口诀必背同号相加才可能溢出异号相加永不溢出。 正 正 负 → 正溢出负 负 正 → 负溢出。异号相加为什么永不溢出一正一负结果必然夹在两者之间绝对值只会更小不可能越界。软考还爱考硬件层面的两种判法双符号位变形补码用两位符号位正数 00、负数 11运算结果两位不同即溢出——01正溢出10负溢出进位判法数值位向符号位的进位与符号位向更高位的进位两者不一致即溢出。六、顺手补一刀定点小数的范围以上都是定点整数。如果考定点小数纯小数小数点在符号位之后范围不一样这是软考的另一把刀码制定点小数范围8位原码-(1-2⁻⁷) (1-2⁻⁷)即 ±127/128补码-1 (1-2⁻⁷)注意补码可以表示-1编码1.0000000和定点整数的 -128 是同一类特例——最小值能多跨一步0 又唯一。很多考生把整数范围的直觉搬过来错选 -127/128那是原码的范围。七、10 道练习题基础题1~51.机器字长为 8 位采用原码表示定点整数其表示范围是 。A. -127 127 B. -128 127 C. -127 128 D. -128 1282.已知 X -19机器字长为 8 位则 [X]补 为 。A. 10010011 B. 11101100 C. 11101101 D. 111011103.某 8 位补码为 11101101其十进制真值为 。A. -19 B. -18 C. 109 D. -1094.机器字长为 8 位用补码表示带符号整数时可表示的不同数值共有 个。A. 255 B. 256 C. 127 D. 1285.下列码制中数值 0 的机器数表示唯一的是 。A. 原码 B. 反码 C. 补码 D. 以上都不是进阶题6~10带坑6.某 8 位机器数为 10000000若按补码解释其真值为 。A. -0 B. -128 C. -127 D. 1287.某 8 位数的移码为 01110011则该数的补码为 。A. 11110011 B. 11110010 C. 01110011 D. 100011018.在 8 位补码系统中下列运算会发生溢出的是 。A. (60) (60) B. (-100) (-50) C. (100) (-120) D. (-128) (127)9.采用双符号位变形补码进行补码加法运算若运算结果的两个符号位为 10则表示 。A. 结果为正无溢出 B. 结果为负无溢出 C. 发生正溢出 D. 发生负溢出10.机器字长为 8 位采用补码表示定点小数纯小数小数点在符号位之后则可表示的最小值为 。A. -1 B. -127/128 C. -128 D. -1/128八、答案与详解1. A原码的 0 有两种表示00000000 和 10000000浪费一个编码范围为 -(2⁷-1) ~ (2⁷-1) -127 ~ 127。选 -128 的都是把补码范围记串了。2. C19 0010011。-19 原码10010011→ 反码11101100符号位不变、数值位取反→ 补码11101101末位 1。A 是原码B 是反码——软考就爱把中间过程放在选项里等你。3. A补码求真值原路返回数值位1101101取反得00100101 得0010011 19符号位为 1 →-19。和第 2 题互为逆运算两题可以互相验算。4. B8 位补码的 0 唯一8 位二进制共 2⁸ 256 个编码全部对应不同的数256 个-128 ~ 127。选 255 的是没意识到原码/反码才少一个。5. C原码的 000000000、10000000反码的 000000000、11111111补码的 0 只有00000000。注意移码的 0 也唯一10000000如果选项出现补码和移码也要敢选。6. B本题第一坑10000000是补码特例-128没有对应原码直接背。千万别对它做取反加1——那样会得到 128但 128 在 8 位补码里根本不存在绕回来说明它是特殊规定的。选 -0 的是和原码/反码记混了原码里10000000才是 -0。7. A移码与补码只差符号位移码01110011→ 符号位 0 翻成 1 → 补码11110011。验算补码11110011真值 -13移码 -13 128 115 01110011✓。坑点选 B 的多做了1把补码当成反码又加工了一遍选 D 的是错当成求原码。8. B逐项看A 中 6060120 127不溢出B 中 -100 (-50) -150 -128负溢出选它C、D 都是异号相加异号相加永不溢出。机器视角验证 B-100 补10011100 -50 补1100111001101010第9位进位丢弃 106负负得正溢出坐实。9. D双符号位判溢出两位相同00 或 11无溢出两位不同即溢出01 正溢出10 负溢出。坑点01/10 谁正谁负容易记反。记法结果的高位符号是 0 说明被顶成了正的样子——是负数顶爆了负溢出……不好记的话就用硬背1 开头 10 → 负0 开头 01 → 正和最高位的数字同向。10. A本题大坑定点小数的补码范围是-1 ~ (1-2⁻⁷)最小值-1编码1.0000000。选 B-127/128是把原码定点小数的范围搬过来了选 C-128是把定点整数的范围搬过来了。三种情形对比背整数补码最小 -128、小数补码最小 -1、小数原码最小 -(127/128)。九、五句话带走正数三码合一负数补码 反码 1补码范围 -2ⁿ⁻¹ ~ 2ⁿ⁻¹-1负数多一个-128 是特例0 唯一的是补码和移码移码 补码翻符号位保序所以给阶码用同号相加才可能溢出正正得负是正溢出负负得正是负溢出。这 3 分此后就是你的了。