十进制的 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 ]