深入理解计算机底层为什么采用补码运算如何理解二进制计算高位溢出
Posted Roninaxious
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解计算机底层为什么采用补码运算如何理解二进制计算高位溢出相关的知识,希望对你有一定的参考价值。
在计算机底层运算设计的过程中,是根据现实生活中的数学运算做出的映射。比如数学中的8-3=8+(-3),那么这样一来减法运算就变成了加法运算(你这时可能会问,我脑子直接计算8-3=5了,何必再转换位成加法运算多此一举,只能说你日常形成习惯了吧!因为对8-3做分解就只有8和-3这两部分,所以在数学中就是8和-3做相加),因此计算机底层设计模拟数学就需要负数,这个负数就可以使用反码进行充当–》本质上是为了将减法运算转换为加法运算。补码是为了解决数字“0”在计算机中非唯一编码的问题。为什么会这样,往下看!
Computer_Base__Binary_List:
1.为什么计算机内部只有加法器?
我们都知道计算机芯片内部有个核心部件-晶体管,但你知道它的作用吗?作用很多,此处列举一个与本文相关的。
通过三极管的拼接可以完成逻辑的运算,制造出了与非门。(至于为什么本文不做探讨)
(1)与门:两个输入端和一个输出端,当输入端都为高电平(1)时,才能输出高电平(“&”)
(2)非门:一个输入端和一个输出端,当输入端为高电平(1)时,输出端为低电平,“非”也就是相反的意思。(“!”)
(3)或门:两个输入端和一个输出端,当某一个输入端为高电平(1),那么输出端就为高电平。(“|”)
最终通过与门、非门、或门的有机结合创造出了加法器。有了加法器还要解决减法器的问题,这个减法器的设计更为困难(比如加法器可以使用“与”来完成进位),所以为了硬件电路变得简单,我们可以通过加法器实现减法器的功能。这就涉及到了补码。
2.计算机为什么会需要原码、反码、补码?
二 进 制 第 一 位 一 般 会 表 示 成 符 号 位 , 0 正 , 1 负 二进制第一位一般会表示成符号位,0正,1负 二进制第一位一般会表示成符号位,0正,1负
🌹(1)原码
将一个整数转换为二进制形式就是其原码。
比如byte a = 3;那么a的原码就是0000 0011
比如short a = 3;那么a的原码就是0000 0000 0000 0011
比如int a = 3; …
如何理解不同类型等到二进制位数呢?
一个byte占1个字节(一个字节也就是8位二进制数)
一个short int 占用2个字节(也就是16位二进制数)
一个int 占用4个字节(也就是32位二进制数)
…
总结:简单了说原码就是一个整数的二进制形式。
🌹(2)反码
对于正数,它的反码和原码相同。
比如short a = 3, 它的反码=原码=0000 0000 0000 0011
对于负数,它的反码是将原码中除了符号位以外的所有位进行取反获得。(也就是0变1,1变0)
比如short a = -3,那么它的原码是1000 0000 0000 0011,它对应的反码是1111 1111 1111 1100.
有了原码为什么还会需要反码呢?
这就类似于数学中的4-2=4+(-2),反码相当于负数,可以将减法变成加法。
🌹(2)补码
有了反码为什么还需要补码呢?
这其实是因为0这个模糊的概念造成的。8位二进制反码表示的正数范围为(0000 0000 ~ 0111 1111,高位为符号位),也就是+0~127;8位二进制反码表示的负数范围为(1000 0000 ~ 1111 1111),也就是-127 ~ -0。
其中涉及到了两个特殊的编码+0和-0。由于计算机中的编码是唯一的,所以需要解决这个问题。
官方给出的解决方案是正数范围保持不变,负数范围整体向后移动一位,也就是反码+1.(所以负数范围就变成了128~-1)
有位大佬说的很贴切,这种操作好像是在反码上打了“补丁”,修正了一下,所以称之为补码。
这样一来补码就很清晰了
正数的补码和原码一致
负数的补码=反码+1
总结:补码是为了解决数字“0”在计算机中非唯一编码的问题。
3.如何理解二进制计算高位溢出?
这就是涉及到了模运算。
很多技术朋友都是列举的是时钟的例子,可能这个比较容易理解吧!
假设当前时钟指向4点,怎么将它指向2点呢?
1.直接向后拨动两位到2点【4-2=2】
2.向前拨动十位就到2点了【(4+10)mod 12】
从以上我们可以看出-2和10在数学上互为补数
所以可以总结出
A-B=(A+B补)mod N(N表示极限值)
看下面的二进制补码计算溢出的情况
4-3=? 【假设这两个都是byte类型,也就是一个字节,8位二进制数】
4的补码为0000 0100
-3的补码为1111 1101
相加之后为1 0000 0001,可以看出已经超出了byte的-128~127的范围,由于存储限制,进位1会被丢弃。
最终的结果0000 0001,对应的十进制也就是1,刚好满足结果,你可能会有疑问为什么这么巧呢?
原因如下:
这就类似于上面涉及到的模运算,1 0000 0000刚好是该byte的极限值,由于计算机存储的限制,所以会将高位1进行舍弃。其值就是0.
对于-3我们可以理解为0-3,0-3对应的二进制也就是1 0000 0000 - 0000 0011 = 1111 1101 = -3的反码 + 1 = -3的补码。
另外也可也可以利用上面的mod进行理解这个溢出。
以上是关于深入理解计算机底层为什么采用补码运算如何理解二进制计算高位溢出的主要内容,如果未能解决你的问题,请参考以下文章
2017-2018-1 20179215 《深入理解计算机系统》第二章