二进制,十六进制,二进制与十进制的转化运算c++
根据冯诺依曼结构的运算器,只有加法运算器,没有减法运算器算法
因此,计算机中不是直接作减法,是经过加法来实现的。因此就必须引入一个符号位设计
原码,反码,补码 的产生就是为了解决这个问题3d
最简单的机器数表示法code
原码:blog
最高位表示符号位,1表示负,0表示正class
其余位存放该数的二进制的绝对值基础
直接用原码运算原理
0001+0010=0011 (1+2=3)正确 0000+1000=1000 ((+0)+(-0)=-0) 0001+1001=1010 (1+(-1)=-2)出错 1001+1001= ?
原码正数之间的加法一般不会出错硬件
正数与负数相加,或负数与负数相加,问题就出现了
因此,原码直观易懂,易于正值转换,但用来实现加减法的话,运算规则总归是太复杂,因而反码来了
原码最大的问题就在于一个数加上他的相反数不等于零,反码的设计思想就是为了解决这一点
反码:
正数的反码=原码
负数的反码=原码除符号位外,按位取反
咱们试着用反码运算
0001+1110=1111 (1+(-1)=(-0)) 有点问题,也正确 1110+1101=1011 (-1)+(-2)=(-4) 两个负数相加,出错
负数相加出错,问题不大,咱们只须要在两个负数相加时,将两个负数反码包括符号位所有按位取反相加,而后再给他的符号位强置‘1’就能够了。
反码表示法其实已经解决了减法的问题,他不只不会像原码那样出现两个相反数相加不为零的状况,并且对于任意的一个正数加负数,计算结果是正确的
而后就有了补码
补码:
正数的补码=原码
负数的补码=反码+1
负数的补码的另一种算法:
自低位向高位,尾数第一个1及其右部的0保持不变,左部取反,符号位不变
其实上面两段话,都只是补码的求法,而不是补码的定义,基础工做者并不会心血来潮的把反码+1就定义为补码,只不过是补码正好就等于反码加1罢了
暂时先忘记书上那句负数的补码等于它的反码+1,咱们的理解陷入了误区
这也是为何《计算机组成原理》要**特地先讲补码,再讲反码
接下来咱们要重点讲讲补码的思想
为了理解,先得引入模和同余的思想
模 其实就是一个计量器的容量大小,好比钟表的模M=12
同余 是指两个整数A和B除以同一个正整数M,所得余数相同,好比1点和13点,2点和14点就是同余的,能够写做
1 = 13 mod (12), 2 = 14 mod (12)
若是说如今时针如今停在10点钟,那么何时时针会停在8点钟呢?
这么说吧,由于过去2个小时前是8点,因此将来10个小时候也是8点
也就是说:倒拨2小时 或 正拨10小时 都是八点钟
10-2=8,(10+10)mod(12)=8
因此,10-2和10+10从另外一个角度来看是等效的,它都使时针指向了8点钟
既然是等效的,那在时钟运算中,减去一个数,其实就至关于加上另一个数(这个数与减数相加正好等于12,也就是同余数)
我再次强调,原码,反码,补码的引入是为了解决作减法的问题。在原码,反码表示法中,咱们把减法化为加法的思惟是减去一个数,等于加上一个数的相反数,结果因为引入符号位形成了各类问题
那你应该知道我要说什么了,利用模和同余的概念,咱们能够使减法运算转化为加法运算
而如今,咱们不引入负数的概念,就能够把减法当成加法来算
因此接下来咱们聊4位二进制数的运算,也没必要急于引入符号位。由于补码的思想,把减法当成加法时并非必需要引入符号位的。
并且咱们能够经过下面的例子,也许能回答另外一个问题,为何负数的符号位是‘1’,而不是正数的符号位是‘1’
0110 - 0010 (6-2=4) 计算机中没有减法器,不能直接算
可是如今你知道,减去一个数,能够等同于加上另一个正数(同余数)
那么这个数是什么呢?时钟运算中咱们能够看出这个数与减数相加正好等于模M=12
四位二进制数的模(计量器)=四位二进制数最大容量=2^4=16=10000B
那么2(0010)的同余数,就等于10000-0010=1110(14)
既然如此
0110(6) - 0010(2) = 0110(6) + 1110(14) = 10100(16+4=20)
OK,咱们看到按照这种算法得出的结果是10100,可是对于四位二进制数,最大只能存放4位(硬件决定),正好是0100(4)
,就是咱们想要的结果,至于最高位的1
,计算机会把他放入psw寄存器进位位中。8位机则会放在cy中,x86会放在cf中(不做讨论)
这个时候,咱们再想一想在四位二进制数中,减去2,就至关于加上它的同余数14
可是减去2,从另一个角度来讲,也是加上(-2)。即加上(-2)和加上14其实获得的二进制结果除了进位位,结果是同样的。
若是咱们把1110(14)的最高位看做符号位后就是(-2)的补码,这可能也是为何负数的符号位是‘1’而不是‘0’,
并且在有符号位的四位二进制数中,能表示的只有‘-8~7’,而无符号位数(14)的做用和有符号数(-2)的做用效果实际上是同样的。
那正数的补码呢?加上一个正数,加法器就直接能够实现。因此它的补码就仍是它自己。
到这里,咱们发现原码,反码的问题,补码基本解决了。
作减法时,0001(1)+1111(-1)=0000
,咱们不再须要一个1000
来表示负0
了,就把1000规定为-8
负数与负数相加的问题也解决了1111(-1)+1110(-2)=1101(-3)
而后咱们再来看看为何负数的补码的求法为何是反码+1
由于负数的反码加上这个负数的绝对值正好等于1111,再加1,就是1000,也就是四位二进数的模
而负数的补码是它的绝对值的同余数,能够经过模减去负数的绝对值,获得他的补码。
因此,负数的补码就是它的反码+1
若是咱们把-8当成负数的原点。那么-5的补码是多少呢?
-5 = -8 + 3
-5的补码就是-8的补码加3
1000(-8) + 0011(3) = 1011(-5)
也能够记住-1的补码是1111
口算减法得出
1111(-1) - 0100(4) = 1011(-5)
对于八位加法器的话,能够把-128
当补码原点。十六位能够把-32768
当补码原点。
是的,128
是256
(八位二进制数的模)的一半,32768
是65536
(十六位二进数的模)的一半
也很方便有没有,并且简单的是
补码原点老是最高位是‘1’,其余位是‘0’
感谢阅读