原码、反码、补码
系统总结学习了一下关于计算机中的原码, 反码和补码。并且生日讨论了这些二进制码的原理。
关于机器数
机器数是把符号”数字化”的数,是数字在计算机中的二进制表示形式。这和计算机内部的硬件有关,它只能表示两种物理状态(0和1),于是计算机就用二进制数。
在实际中数字是有符号的,通常在机器里就用一位二进制的0或1来区别。通常这个符号放在二进制数的最高位,称符号位,以0代表符号“+”,以1代表符号“-”。
带符号位的机器数对应的数值称为机器数的真值。 例如:机器数1011011
的真值对应为-011011
。
1、机器数的类型
机器数可以分为定点数和浮点数。定点数通常表示整数(也可以表示浮点数),浮点数通常表示实数(实数包括有理数和无理数)。
2、整数表示
//TODO
原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是28个,即[-127,127]。
反码
正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。比如:
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
补码
正数的补码就是其本身,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)。比如:
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
原码, 反码和补码的关系
为什么需要这么多种表示法?原码通常是与人脑最容易理解和计算的表示方式;反码和补码通常和计算有关系。在正数表示中三码相同,而负数三码不同。
根据运算法来,一个正数减去一个正数等于加上一个负数,即: 1-1 = 1 + (-1) = 0
,而机器只有加法没有减法,而如果符号位参与计算会怎么样?比如:
00000001
+10000001
---------
10000010
换算结果是-2显然结果不对,如果采用补码计算,如:
00000001
+11111111
---------
100000000
因为机器只支持8位所以进位的1会被丢弃,结果为0,只有就达到了有符号运算的效果。但是为什么?其实10000000
相当于111111+1
,所以上面的计算过程相当于1000000-1-111110=000001
。计算公式分两种情况:
1.如果X小于Y,那么Z是一个负数。这时,我们就对Z采用2的补码的逆运算,求出它对应的正数绝对值,再在前面加上负号就行了。所以,
Z = -[11111111-(Z-1)] = -[11111111-(X + (11111111-Y) + 1-1)] = X - Y
2.如果X大于Y,这意味着Z肯定大于11111111,但是我们规定了这是8位机,最高的第9位是溢出位,必须被舍去,这相当于减去100000000。所以,
Z = Z - 100000000 = X + (11111111-Y) + 1 - 100000000 = X - Y