为什么需要补码
在真实世界里,常常需要负数。如果存储在存储设备中的最小值为0,那么计算机如何存储负数呢?这个问题不是存储问题,而是程序设计人员的解释问题,类似这样的问题在后边的存储设备中也存在( 关注下一篇)
百科概念
计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
从百科解释来看是为了减少硬件电路设计,这是最终目的。从设计目的来看实在感慨设计师的巧妙。
下面我们分析一下,为什么原码取反加一就能够减少硬件电路,换句话说,为什么取反加一就可以将减法转化为加法?
定义和原理
从百科来看,给补码下个定义比较困难,就好比解释什么是筷子一样。我们可以抛开计算机,从人类社会数学的概念出发,给补码定义如下:
所谓补码就是某个数n,这个数加上-n=0。这也是补码的基本原理。
我们将二进制的首位为0解释为正数,1解释为负数
补码.jpg
13 00001101
-13 11110011(补码)
1 00000000
直接从以上等式来看,13和-13之间除了符号位不一样,其实位之间并无关系。而实际上他们之间的关系十分微妙。
这里可能有人会想,为什么不直接将符号位取反即表示负数?比如+13(+一般省略)和-13在十进制中就是符号不一样。
理论上单纯从解释的角度出发没有问题
00001101 (+13)
10001101 (-13)
但无法将该种解释通过加法来实现减法.(因为二进制相加之后不为0)
那么这种微妙的关系是什么呢?
通过补码的定义
n+(-n)=0
这里的(-n)即为补码.我们反推过来,这里n已知,0已知(00000000).
如何求-n?
我们知道给定一个数n,让这个数变为0有两种办法
做减法,将这个数的每一位减1,这个办法在百科的概念中可以被否决,因为要增加硬件成本.
做加法,让结果溢出后即为0
根据第二种办法我们得出
最大的数+1即可溢出为0
那么n+(-n)=0 成立,-n推导如下
已知
0=(11111111+1)
11111111
1
1 00000000
=>
n+(-n)=(11111111+1)
已知
n|~n=11111111
n+(-n)=(n|~n)+1
n+(-n)=(n+~n)+1(二进制按位或即按位相加)
=>
(-n)=~n+1 (等号两个n抵消)
总结
通过以上分析,真的感慨计算机大师的微妙设计。
通过数学的巧妙设计使cpu中不需要减法器电路以减少设计成本。
作者:zh_harry
链接:https://www.jianshu.com/p/f774a73a06ad
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。