du blog
Hello, welcome to my blog
原码、反码、补码
created: Mar 6 21updated: Mar 6 21

原码

十进制的 10 转换为 二进制为 1010

那么十进制的-10 转换为二进制呢?

为了在二进制想办法表示负数,于是人们想出来一个办法:

在二进制数值前边加一个符号位(即最高位为符号位),正数情况下该位数为0,负数情况下该位数为1,其余位表示数值大小

这样的话 十进制10 转换为二进制 为 0 1010;十进制 -10 转换为二进制为 1 1010

这种编码方式称为原码,原码的优势比较明显:非常直观,容易被人理解

使用原码存在的问题:

使用原码解决了十进制数的储存问题,但是计算机中还有另外一个操作,那就是计算

首先,原码对于加法是没有问题的,如 5 + 2:

对应的二进制运算为 0 0101(原) + 0 0010(原) = 0 0111(原),对应的十进制为7 是没有问题的

其次,试着使用原码进行减法,例如10 - 2:

那么就是 0 1010(原) - 0 0010(原) = 0 1000(原),转换为是进制刚好为8,这样看起来好像是没有问题的,但是这只是我们一厢情愿的算法,在计算机中算术逻辑单元(ALU),并没有直接进行减法运算,对于减法,也是通过加法器来实现的,

也就是说,计算机中所有的减法运算都要转换称为加法运算,比如 10 + (-2):

它们的二进制运算为 0 1010(原) + 1 0010(原) = 1 1100(原),转换为十进制为 -12 ,这明显是错误的

可见,原码虽然对人来说理解比较直观,但是对于计算机来说却带来了很大的计算难度

反码

虽然原码对于人来说很容易被理解,但是对于计算机的计算却带来了一定的困难,尤其是减法运算,所以人们发明了反码来解决减法运算问题

反码是基于原码计算得来的,表示方式为:正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各个位取反

如:

10 的原码为 0 1010 那么它的反码同样为 0 1010

-2 的原码为 1 0010 那么它的反码为 1 1101

有了反码之后,二进制的运算就可以带着符号位一起了,并且可以直接将减法转换为加法进行运算,但是使用反码进行运算需要注意以下几点:

· 反码运算时,其符号位参与运算

· 反码的符号位相加之后,如果有进位出现,则要把它送到最低位去相加(循环进位)

· 用反码进行运算,其结果亦为反码,在转换为真值的时候,若符号位为0,则数位不变,若符号位为1,应将结果取反,才是其真值

如,10 - 2,在计算时需要转换为 10 + (-2)进行计算,

0 1010(反) + 1 1101(反) = 0 0111(反) + 1(进位) = 0 1000(反), 因为符号位为0,表示为正数,所以它对应的原码也为 0 1000(原),则十进制值为 8

如:2 - 10, 在计算是需要转换为 2 + (-10),进行计算

0 0010(反) + 1 0101(反) = 1 0111(反) 因为符号位是1,所以除了符号位取反,则真值为 1 1000(原),则十进制为 -8

但是反码还存在一个问题:

我们尝试计算 10 - 10,即 10 + (-10):

0 1010(反) + 1 0101(反) = 1 1111(反),因为符号位为1,表示负数,所以其它位取反,则原码为 1 0000(原),则十进制为 -0

虽然很多人都能理解 +0 和 -0,但是 0 带符号确实是没有意义的,如果计算机用八位表示数字,那么0就有两种:0000 0000 和 1111 1111,分别表示 +0 和 -0

补码

虽然反码解决了 减法的问题,但是对于 0 的符号的问题,却没有解决,于是就出现了补码,

补码是在原码和反码的基础上衍生出来的,补码的表示方法是:正数的补码是其本身,负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后加 1(即在反码的基础上+ 1).

补码的计算规则:

· 补码运算时,其符号位参与运算,

· 补码的符号位相加之后,若出现进位,则进位舍弃,

· 使用补码运算,其结果亦为补码,在转换称为原码时,如果为正数,则其补码就是原码,如果是负数,则补码的补码就是其原码

我们采用补码的方式 计算 10 - 10

0 1010(补) + 1 0110(补) = 0 0000(补) 因为其符号位是 0 则其原码也是 0 0000(原),对应十进制为 0

有了补码的方式,0的表达方式就唯一了,

此外,如果使用原码或者反码,8位的原码或者反码,能表示的最小数字为 -127,而使用补码,能表示的最小数字为 -128,可见,使用补码,不仅能修复0的符号问题,而且能多表示一个最低位,这也就是为什么8位的二进制,使用原码或反码的表示范围为[ -127, +127 ],而使用补码则为[ -128, +127 ]

总结使用补码的原因:

1. 计算机的运算器为了实现简单,会将减法转换为加法,统一使用加法计算,想要把加法转换为加法,就需要在运算时带着符号一起运算,而反码和补码可以带着符号一起运算,也就方便了将减法转换为加法

2. 采用补码,可以解决编码中存在 +0 和 -0 两种表达 0 的方式

3. 补码的标识范围比原码和反码大,如8位的二进制,原码和反码的表示范围为[ -127, + 127],而使用补码的表示范围为 [ -128,+127 ]

总结摘要自: https://mp.weixin.qq.com/s?__biz=Mzg3MjA4MTExMw==&mid=2247493568&idx=1&sn=8c445ca35300fde5a4f53685cc564dac&chksm=cef61476f9819d603a9f15690267885e8b96c90747c71f9c8408b4bdfe0d1c515ee0fc3b8847&scene=21#wechat_redirect