关于原码/反码/补码/移码

前言:关于原码反码补码的学习笔记

记录自己的所学下来的知识和自己思考的问题,自己在学习的时候计组都是做笔记在书上,但是自己的字写的真的太难看了,翻的时候看不太懂,因为符号位的相关知识点会比较好理解,就就不记录了

  • 计算机中你定义的有符号数和无符号数存储到内存中你会发现都是补码的形式...

原码

什么是原码?一句话就可以表示,原码是机器数的一种最简单的表示形式,符号位为0表示正数,符号位为1表示负数,数值位即是真值的绝对值,所以原码又被称作为带符号位的绝对值表示

  • 符号位0表示正数,符号位1表示负数

  • 机器数是什么东西?就是计算机内存地址中存储的数值,将带符号位的机器数对应的真正数值称为机器数的真值,所以计算机中存储的都是带符号位的数值

  • "数值位即是真值的绝对值,所以原码又被称作为带符号位的绝对值表示"如何理解?首先要知道的一点是"数值位"的概念,我这里举个例子,假如一个存储单元的地址是8位的,那么我存储的就是0,1010101,那么数值位就是1010101,那么这里的话就是7位数值位,而符号位就是0

  • 上面还会看到一个,逗号的符号,这个其实就是区分符号位和数值位的一个标识符,实际内存中是不存在的

我感觉原码的概念完了,那么还有就是原码的运算,分为整型和小数的运算,我这里就举几个例子,以后复习的时候看看

整型的情况下,我这里数值位当作4位来进行计算,所以不要问为什么数值位是4位

当[x]真值=+1110的时候,代入公式中,[x]原 = 0,1110

当[x]真值=-1110的时候,代入公式中,[x]原 = 2^4-(-1110) = 10000 + 1110 = 11110 ---转化为符号位---> = 1,1110 (因为最高位是符号位)

小数的情况下:

当[x]真值 = +0.1101,代入公式中,[x]原 = 0,1101

当[x]真值 = -0.1101,代入公式中,[x]原 = 1-(-0.1101) = 1.1101

原码表示法的问题

1、第一个问题

如果我们求的一个数是[x]真值 = 0的情况下,那么这里的话就分为两种情况,分别要求的是 [+0.0000]原码 和 [-0.0000]原码

[0.0000]原码,这里通过定义来进行求得,当情况是该值算作为大于等于0,所以+0.0000的原码就是自身

[-0.0000]原码,这里通过定义来进行求得,当情况是该值2^4-0,那么结果就是11,0000,然后高位舍去,最终的结果就是1,0000 ,所以对于[-0.0000]原码是1,0000

那么这里问题就来了,原本两个数按道理来说应该是相等的,但是到了内存中存储的话却存储了两种形式的数据

2、第二个问题

如果使用原码,那么当两个操作数符号不同,但是要进行相加的时候,那是不是就需要用到减法器,而按道理来说通过减法器应该是能够解决的,而减法器又会引出了一个资源浪费和运算步骤增多的问题,而如果用加法器统一处理加法和减法的话就可以解决这个资源浪费的问题

而下面通过补码的形式来存储就成功的解决了上面的这两个问题。

补码

在讲补码之前先引入一种模的思想,就比如上面提到的一个问题"当两个操作数符号不同,但是要进行相加的时候,那是不是就需要用到减法器,而按道理来说通过加法器应该是能够解决的"

那么这里通过模就可以来进行解决,比如我这里设置模为12,就以时钟为准,此时是3点钟,如果我想让它转到12点钟是不是有两种方法?

  • 第一种方法就是顺时针旋转9个钟头,这里可以理解为+9,因为3+9=12

  • 第二种方法就是逆时针旋转3个钟头,这里可以理解为-3,因为3-3=0,而12其实就是0,因为12模12为0

通过这个模的思想就可以解决原码不同符号位想减而不用减法器的问题,其实也就是减去一个数A,那么只需要加上这个数A对应的补数就好了

这里就举个例子,就比如A-B=9-5=4,但是这里是减法的,然后这里在通过模的思想来转化为加法,对于模12而言,-5的补数就是7,那么这里的话就是9+7=16,因为模12,所以最终的结果还是4,那么这里就实现了通过模来实现加法代替减法的操作,而在计算机中补码就是通过这个模的思想,只是称呼为补码而已,所以说在计算机中通过补码使得所有运算都能用加法运算器来实现,不再需要减法运算器,如下介绍所示

对应的补码的定义公式如下所示

  • 单纯个人理解,可以看到大于0的情况下,其实原码反码补码都是一样的,再想下,本来就是正数的真值,那我何必需要在转化什么呢?本来就是通过加法,那我为什么还要改呢?

  • 然后小于0的情况,那么这里的话就会需要用到减法,所以补码的定义公式中就会通过求对应的补数,将其转化为正数,然后就可以通过加法的方式来求得对应的结果了

这里还讲下一个2^(n+1)次方,这里的n字母是数值的有效位数,在二进制中这个数就可以代表你当前范围内的一个模数,以这个模为准。

这里再举个例子,我们想要计算 2-5 的操作

那么先通过原码来实现,2对应的原码就是0,0000010 5对应的原码就是

参考文章:https://zhidao.baidu.com/question/1111894771109038579.html

然后我这里再抛出一个问题,假如内存中存储的一个存储单元的位数为8位,为什么10000000实际上代表的真值为-128?

我查阅了相关的资料,有两种方法都可以得到这个数

  • 第一种方法,通过定义来求,这里当操作数有8位,其中一位是符号位,数值位有7位,然后通过定义得到2^8+(-0,1111111)(也就是128)

  • 第二种方法,其实也是通过定义来计算,你可以通过-127-1,也就是(-127)+(-1),分别计算出-127和-1的补码形式

-127 -> 1,0000001
-1 -> 1,1111111
1,0000001 + 1,1111111 = 1,0000000

同样可以算出-128为1,0000000

反码

移码

移码的作用就是方便计算机比较两个数比较其数值的大小,计算机只能通过一位一位的比较,它只知道1比0大,所以移码就是为了屏蔽那些符号位的干扰,让计算机轻松的比较数值的大小

我自己感觉移码用的不多,定点和浮点那边也只是稍微的用到,会套公式就行了

比如下面的图,+21 对应的补码是 0,10101 ,-21 对应的补码是1,01011,由于符号位的影响导致了最高位的变化,而计算机只能通过一位一位来进行比较,这就导致符号位不同的两个数比较大小的时候会出现问题,那么最终出现的问题就是-21是大于+21的,但是实际上是+21是大于-21的

而移码的解决方式就是通过对应的真值加上2^n,n为数值位的位数,这样就能解决符号位的问题

这里你还会发现一个规律就是移码和补码其实就相差了一个符号位,所以通过补码可以很快的得到对应的移码

posted @   zpchcbd  阅读(753)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2020-04-17 浏览器的解码与编码
2020-04-17 PHP 反序列化中的session考点
点击右上角即可分享
微信分享提示