原码,补码,反码详解
今天由传智播客教师给各位解说盘算机的原码, 反码和补码. 并且举行了深化探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法盘算原码的减法.。
一. 机器数和真值
在学习原码, 反码和补码之前, 必要先了解机器数和真值的看法.
1、机器数
一个数在盘算机中的二进制表现情势, 叫做这个数的机器数。机器数是带标记的,在盘算机用一个数的最高位存放标记, 实数为0, 正数为1.
好比,十进制中的数 +3 ,盘算机字长为8位,转换成二进制就是00000011。假如是 -3 ,就是 10000011 。
那么,这里的 00000011 和 10000011 就是机器数。
2、真值
机器数的第一位是标记位,后边才是真正的数值,以是机器数的情势值就不即是真正的数值。比如外表的有标记数 10000011,其最高位1代表负,其真实数值是 -3 而不是情势值131(10000011转换成十进制即是131)。以是,为区别起见,将带标记位的机器数对应的真实数值称为机器数的真值。
例:
0000 0001的真值 = +000 0001 = +1
1000 0001的真值 = –000 0001 = –1
二. 原码, 反码, 补码的基本看法和盘算办法.
在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的看法.关于一个数, 盘算奥密使用一定的编码办法举行存储. 原码, 反码, 补码是机器存储一个具体数字的编码办法.
1. 原码
原码就是标记位加上真值的相对值, 即用第一位表现标记, 其他位表现值. 好比假如是8位二进制:
[+1](原码) = 0000 0001
[-1](原码) = 1000 0001
第一位是标记位. 由于第一位是标记位, 以是8位二进制数的取值范围就是:
[1111 1111 , 0111 1111]
即
[-127 , 127]
原码是人脑最容易了解和盘算的表现办法.
2. 反码
反码的表现办法是: 实数的反码是其本身,正数的反码是在其原码的基本上, 标记位安定,其他各个位取反.
[+1] = [00000001](原码)= [00000001](反码)
[-1] = [10000001](原码)= [11111110](反码)
可见假如一个反码表现的是正数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再盘算.
3. 补码
补码的表现办法是:实数的补码就是其本身,正数的补码是在其原码的基本上, 标记位安定, 其他列位取反, 最初+1. (即在反码的基本上+1)
[+1] = [00000001](原码) = [00000001](反码) = [00000001](补码)
[-1] = [10000001](原码) = [11111110](反码) = [11111111](补码)
关于正数, 补码表现办法也是人脑无法直观看出其数值的. 通常也必要转换成原码在盘算其数值.
三. 为何要使用原码, 反码和补码
在开头深开学习前, 我的学习发起是先”意会贯穿”外表的原码, 反码和补码的表现办法以及盘算办法.
如今我们晓得了盘算机可以有三种编码办法表现一个数. 关于实数由于三种编码办法的后果都相反:
[+1] = [00000001](原码) = [00000001](反码) = [00000001](补码)
以是不必要过多表明. 但是关于正数:
[-1] = [10000001](原码) = [11111110](反码) = [11111111](补码)
可见原码, 反码和补码是完全不同的. 既然原码才是被人脑直接识别并用于盘算表现办法, 为何还会有反码和补码呢?
起首, 由于人脑可以晓得第一位是标记位, 在盘算的时分我们会依据标记位, 选择对真值地区的加减. (真值的看法在本文最开头). 但是关于盘算机, 加减乘数以前是最基本的运算, 要计划的尽力简便. 盘算机区分”标记位”显然会让盘算机的基本电路计划变得十分繁复! 于是人们想出了将标记位也到场运算的办法. 我们晓得, 依据运算端正减去一个实数即是加上一个正数, 即: 1-1 = 1 + (-1) = 0 , 以是机器可以仅有加法而没有减法, 如此盘算机运算的计划就更简便了.
于是人们开头探究 将标记位到场运算, 并且只保存加法的办法. 起首来看原码:
盘算十进制的表达式: 1-1=0
1 – 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
假如用原码表现, 让标记位也到场盘算, 显然关于减法来说, 后果是不准确的.这也就是为何盘算机内里不使用原码表现一个数.
为了处理原码做减法的成绩, 显现了反码:
盘算十进制的表达式: 1-1=0
1 – 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
发觉用反码盘算减法, 后果的真值局部是准确的. 而唯一的成绩但是就显如今”0″这个特别的数值上. 固然人们了解上+0和-0是一样的, 但是0带标记是没有任何意义的. 并且会有[0000 0000]原和[1000 0000]原两个编码表现0.
于是补码的显现, 处理了0的标记以及两个编码的成绩:
1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原
如此0用[0000 0000]表现, 而从前显现成绩的-0则不存在了.并且可以用[1000 0000]表现-128:
(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补
-1-127的后果应该是-128, 在用补码运算的后果中, [1000 0000]补 就是-128. 但是注意由于实践上是使用从前的-0的补码来表现-128, 以是-128并没有原码和反码表现.(对-128的补码表现[1000 0000]补算出来的原码是[0000 0000]原, 这是不准确的)
使用补码, 不仅仅修复了0的标记以及存在两个编码的成绩, 并且还可以多表现一个最低数. 这就是为什么8位二进制, 使用原码或反码表现的范围为[-127, +127], 而使用补码表现的范围为[-128, 127].
由于机器使用补码, 以是关于编程中常用到的32位int典范, 可以表树模围是: [-231, 231-1] 由于第一位表现的是标记位.而使用补码表现时又可以多保存一个最小值.

















