补码 反码 符号与幅值 符号拓展

Lecea ·
更新时间:2024-11-14
· 843 次阅读

文章目录前言 ´・ᴗ・`符号与拓展反码补码符号拓展总结 ´◡` 前言 ´・ᴗ・` 二进制数有常见的三种表示方法(notation),也就是记法 :(按照时间顺序 发展历程) 符号与幅值 反码 补码 开发这三个抽象的玩意儿只是因为解决 正数 与 负数的表示问题 正数 负数的运算问题(主要是加减 因为其他运算从加减衍生出来) 下面我们来看看 这三个装逼晦涩的东西到底有多简单 不要怂 往下走 符号与拓展

我们想一下 区分正负数 最好的办法就是加一个符号位
这就是 “符号与幅值表示法” 英文是sign and magnitude

sign 符号 magnitude 幅值

这样的话 那8-bits 位宽举例 符号位0为正数 1为负数:

0000 0011 = 310 — 10进制的3 1000 0011 = -3 10 – 10进制的-3 也就1~7位是幅值 第八位是符号位

这种方法比较直观 但是没法用
你试着加减一下 就发现需要很多工作要做
计算机性能就被拖累在每一次加减运算了

于是我们的先辈想了另一种方法:反码

反码

反码的思路来源于 进行减运算的时候 一旦借位 前面的所有0 都变成1 1变成0
比如 我拿0(其实是正零 后面再说 现在来个剧透)举例

010 - 110 0000 0000 - 0000 0001 需要借位 于是就 1111 1110 = -110

发现没有 这个计算机可以直接算 不需要像第一种方法有多余的步骤

当然 计算机将所有运算都化为 加法运算 所以:
实际上运算是这样的:

010 + (-1)10 0000 0000 + 1111 1110 1111 1110 = -110

-1 就是 1 按位取反后的结果 这就是“反码” 或者说“取x的反码” 的含义 :按位取反

由此 我们知道 反码表示法中(8位):

最大的正数 0111 1111 绝对值最大的负数 1000 0000 绝对值最小的负数 1111 1111 = “负零” 010 绝对值最小的正数 0000 0000 = “正零” 010

不要想当然 第1~7位不再是“幅值” ,也就不是通过位权简单加起来完事了的

但是反码带来很大的问题

没有解决第一种方法的 两个零问题(正零 负零) 运算不方便(你可以试试)

你发现 数的符号是确定的 但是如何进行二进制转十进制 就变得比较麻烦
因为第1~7位不再是“幅值” 需要补一个1才行

这就是下一轮的改革:补码

补码

上过课的同学都知道 补码表示法
我要想获得一个数的负数(1与-1) 只需要先求那个数的反码 再加1就行
其实实质上就是上面所说的 因为反码不靠谱 计算机识别数的大小很麻烦 而且还有双零问题
所以我们加个1
仅此而已

这样操作以后 我们发现 识别数字大小变的简单 自然转别的进制也变得简单:
例如:
在这里插入图片描述
注意 符号位用的是负号
在这里插入图片描述

符号拓展

这里针对补码表示法 也间接说明补码的好处
所谓符号拓展 就是16位数转为32位(比自己位宽大的)的时候的运算套路
很明显 多余的位 也就17位到32位 都是没有信息 自动补足
我们看个例子:
在这里插入图片描述
这种有点无脑其实 直接用符号位补足第17~32位
原理就是 减法借位 前面的0都变成1 1都变成1 之前说了

总结 ´◡`

所谓 补码 反码 符号与幅值 就是三个解决正负数表示 运算的三个方法

名称 实质 获取负数形式方法
符号与幅值(sign and magnitude) 解决方法ver1.0 把某一位作为符号位 然后符号位取反
反码(one’s complement) 解决方法ver2.0 按位取反
补码(two’s complement) 解决方法ver3.0 按位取反 再加1

最后 可能你还感兴趣别的内容 这里来几个传送:

想学习数据库嘛? 不妨从MySQL入手
MySQL专栏

python这么火 想要深入学习python 玩一下简单的应用嘛?可以看我专栏 还在持续更新中哦:
python应用

小孩子才做选择 大人全都要!对后端感兴趣吗?收下它吧:)
手把手带你学后端(服务端)
目前在Django框架学习阶段


作者:阮菜鸡



补码

需要 登录 后方可回复, 如果你还没有账号请 注册新账号