补码为什么要+1

关于补码的文章,csdn上面遍地都是,所以我们大可不必搬运别人的文章来装点门面,我写这篇博客是想补充一个问题“补码为什么要+1”的问题,这个问题,博客园有个叫张子秋的文章写的很好,但是最后对补码为什么+1的问题,我想补充得更充分一点。

我们知道,在计算机里面

正整数:补码=反码=原码

[+1] = [0000 0001]原 = [0000 0001]反 = [0000 0001]补

负整数在计算机却是用补码表示的

负整数:补码=反码+1

[-1] = [1000 0001]原 = [1111 1110]反 = [1111 1111]补 (负数补码=反码+1)

【注:最高位为符号位0表示正,1表示负】

我们来做一个计算,验证这个逻辑:

1 + 1 = 2

[0000 0001]原 + [0000 0001]原 = [0000 0010]原 = 2 没问题

[0000 0001]反 + [0000 0001]反 = [0000 0010]反 = 2 也没问题

[0000 0001]补 + [0000 0001]补 = [0000 0010]补 = 2 也没问题

【结论:正数做加法,原码=反码=补码,结果是很显然的,因为正数的原码=反码=补码,不管采用什么方式计算结果都一样】

我们再来看负数相加的情况:

1 - 1=0----> 1 + (-1) = 0

[0000 0001]原 + [1000 0001]原 = [1000 0010]原 = -2 错误

[0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

【最后1111 1111要还原成原码1000 0000,保留符号位,原来反的再复原】

此时,出现-0这个数,虽然我们能理解0和-0是一个数,但是我们又觉得-0是没有意义的,所以作为人类杰出的发明,当然不允许作为整个人类科技的基石【计算机算科技的基石吧】出现这种没有意义的事情【不完美会让科学家们睡不着】,如果让-0存在,那么就会出现[0000 0000]表示+0,[1000 0000]表示-0,这会浪费一个数[1000 0000],我们知道,在8位字长中,最高位作为符号位,那么整个8位字长的数能表示的范围就是[1111 1111]~[0111 1111],即-127~+127,[-127,+127],这中间还有一个[1000 0000],所以应该是[-127....-0,0,+127],计算机的设计者觉得,何不把-0这个编码给到-128,让8位字长能多表示一个数?因此,表示范围变成了[-128,+127],这样看起来很完美。那,有人说为什么不让-0给+128,让表示范围变成[-127,+128],但是这个+128怎么编码?又要让最高位的符号位为0,又要表示一个大于127的数【127占满了7个位】,当然是用-0表示-128最好了,因为-128本来符号位就是1啊。

因此,1-1我们不能用反码计算【反码计算结果为-0】。

我们再用补码计算看看,

[0000 0001]补 + [1111 1111]补 = [0000 0000]补 = [0000 0000]原 = 0 【0是一个正数,0的补码,反码,原码都是0000 0000】

补码计算结果正确。

我们刚才做了一个这样的动作:

1-1= 1+(-1)这好像是把减法转成了加法,对没错,计算机就是这样来设计的。那么计算机是如何把减法转成加法的呢?虽然,我们没法搞清楚计算机里面门电路的设计原理,但是可以搞清楚这个理论依据。

计算机是如何把减法转化成加法的?

我们来做一个有意思的实验:

例:我们有一个活动定在下午6点,假设当前时间是上午9点,我们要把时钟拨到下午6点的方法,有两种,

一种是倒拨3小时,即9-3 = 6 mod 12 = 6;

还有一种是顺时针拨9小时,即9+9=18 mod 12 = 6;

在以12为模的时钟系统中,加9与减3的效果是一样的。这就很好的把减法转成加法计算了。这就是计算机需要的,因为加法的实现要比减法方便得多。

mod是模运算的意思,2 mod 12 = 2,13 mod 12 = 1, 12 mod 12 = 0,11 mod 12 = 11,

当a mod b = c,a和b都是正整数的时候,你可以把取模运算当成求余运算。

 mod运算的本质是把减法转成加法

(9-3) ≡  (9+9) mod 12 = 6,≡是同余的意思),同余的说明见下面的同余定理,这里先不影响我们理解。

那么补码为什么+1

计算机处理负数的时候,是用补码来计算的,我们上面也证明了,出现负数的时候,必须使用补码才能得出正确答案。而,计算机设计中却规定

  负数的补码 = 反码 + 1

那么这个+1是什么原理?科学家看到-0觉得不完美睡不着,我们看到科学家的补码的设计+1看不懂也睡不着。

我们重新做一遍1-1

反码计算: 1-1=1+(-1)= [0000 0001]原 + [1000 0001]原

= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

补码计算: 1-1=1+(-1)=[0000 0001]补 + ([1111 1110]反+0000 0001 ) = [0000 0001]补+[1111 1111]补= 0

+1就对,不加1就错!

[0000 0001] + [1111 1110]反和 [0000 0001] + [1111 1111]补 有什么区别?

这里面是什么原理?

我们回到起点,计算机是想把减法转成加法,当出现负数的时候,用他的同余数来替代。【同余原理下面讲】

再回到钟表:

3-9等价于3+3,我们把-9转成了3,为什么可以这样转变

例:3点要拨到6点

一种是顺时针拨3个小时,即3+3 = 6 ;

还有一种是逆时针拨9个小时,即3-9 = 6;

注意:你很自然这样操作了!你潜意识里面做了什么?

3-9=6这个等式好像不太对,3-9=-6啊,那么6和-6为什么一样了呢?这就是模的作用?顺时针拨3和逆时针拨9,这3+9=12,12就是这个时钟系统的模。

我们再用数学知识来解释为什么-6和6重合了。

根据mod(模)的公式

X mod y = x - y* x/y ⏌-------------取模公式

验证:

6 mod 12 = 6 - 12* 6/12 ⏌ = 6 - 12*⎿ 0.5 ⏌ = 6 - 12*0 = 6 ,符号⎿ ⏌向下取整

-6 mod 12 = -6 - 12 * -6/12 ⏌ = -6 - 12 * ⎿ -0.5 ⏌ = -6 - 12*(-1) = -6+12 = 6

看到没有,6和-6 mod 12同余, 6-6 mod 12,数学真他妈伟大,所以数学才是基石的基石。【,是同余符号】

我们很自然的想到了在钟表里面,3的镜像是-9,也就是3的相反数是-9,或者说-9的相反数是3?

3 mod 12 = 3

-9 mod 12 = -9 - 12 * -9/12 ⏌ = -9 - 12 * ⎿ -0.75 ⏌ = -9 - 12*(-1) = -9+12 = 3

那么在钟表里面,-1的相反数是多少?是不是11?

-1 mod 12 = -1 - 12* -1/12 ⏌ = -1 - 12 * ⎿ -0.09 ⏌ = -1 - 12*(-1) = -1+12 = 11

我们再回到上面1-1的计算中,按照钟表的原理,那么在计算机中-1的镜像是多少?是不是应该是127?

你为什么会想到127?为什么这么自然?

-1的反码是 [1000 0001]原---->[1111 1110]反,这个数如果不看符号位,是多少?是126.

按照钟表的原理,-1的反码不是127吗?

所以,我们要在[1111 1110]反码的基础上再加1【-1的反码是126,补码才是127】,而用补码来表示反码加1.

还是有点牵强!感觉是为了凑这个数。

-1和126有什么关系?【126是取反过来的,为什么要取反?计算机为什么这样设计?】

我们换一种思路:

-1 mod 127 = 126,用数学来解释才是硬道。

-1 mod 127 = -1 - 127* -1/127 ⏌ = -1 - 127*⎿ -0.008 ⏌ = -1 -127*(-1)=-1+12=126

问题来了,我们上面不是很自然的认为-1的镜像是127吗,为什么我们用数学公式算出来是126?

这就是潜意识里面把模自然当成了128所以,得出-1的相反数是127.

                模为127

                  模为128

那为什么不能让-1的相反数直接反过来就等于127呢?

这个做不到,我们看原因

-1反=[1000 0001]原反 = [1111 1110]反=126,而127是[1111 1111](不考虑符号位)

所以,原码取反之后,无法得到127,必须在反的基础上再加1刚好是127。

加1的本质是什么?

加1的本质是让模变成128,这是重点。

那么为什么+1就让模变成了128呢?

我们仔细看上面钟表这个图,当模是127时,表盘上的最大刻度只能是126,如果要让表盘的最大刻度变成127,模必须是128,好好理解这就话。

也许有人说,唉,我用127照样可以对127取模啊,并不是只有小于模的数才可以对该模取模啊。我们要这样想,在模为127的数里面,就没有127这个数,到了127又是一轮了,又归零了,如果你还不好理解,你把模当进制来理解,两个10进制数列竖式计算,里面就不能出现10,满10要进位。

你还可以用127 mod 127 实际上等于0,还是归位到起始位置。

所以,我们在用-1进行计算机运算的时候,必须在反码的基础上加1,只不过我们给这个操作定义一个名字叫补码,本质上是因为-1取反后只能等于126,得不到127才加1的。(加1自然就让mod变成128了)

其实,8位字长的模取值范围是[-128,+127]这个范围的数的模就是128.

【其他字长的原理其实也一样,16位,32位,64位】

至此,补码为什么+1这个问题就解释到这里,不知你是否理解了。

同余定理

两个整数a,b,如果分别除以整数m,得到的余数相等,则称a,b 模 m同余,模常用mod替代。记作:

a ≡ b mod m,≡是同余符号,a和b可以是负数,m一般是正整数(0肯定不可以,不知负数有上面意义,没有去研究)

同余是数论中非常重要的一块,是由德国数学家高斯发明的(1777~1855),其中同余符号≡就是他发明的

同余里面的定理:

(1)反身性(Reflexive Property):若a是整数,则a≡a(mod m);

这个性质很容易理解,11 mod 7 = 4,11 mod 7 = 4,当然11和11 mod 7 同余;

(2)对称性(Symmetric Property):若a和b是整数,且a≡b(mod m),则b≡a(mod m);

11 mod 7 = 4, 4 mod 7 = 4, 11 ≡ 4 mod 7同余,4 ≡ 11 mod 7也同余

(3)传递性(Transitive Property):若a、b和c是整数,且a≡b(mod m)和b≡c(mod m),则a≡c(mod m)。

4 mod 7 = 4, 11 mod 7 = 4, 18 mod 7 = 4,

4 ≡ 11 mod 7,11 ≡ 18 mod 7------> 4 ≡ 18 mod 7

基本模运算

(1)若a≡b(mod m),c≡d(mod m),则a±c≡b±d(mod m);

        4 ≡ 11 mod 7 = 4

        -3 ≡ 18 mod 7 = 4

        1(4+(-3))≡29(11+28) mod 7 = 1, 7(4-(-3))≡-7(11-18) mod 7 = 0

        1(4-3) !≡ -7(11-18) mod 7 前面是a+b后面是a-b这样不同余

(2)若a≡b(mod m),c≡d(mod m),则a×c≡b×d(mod m);

        4 ≡ 11 mod 7 = 4

        2 ≡ 9 mod 7 = 2

        8 ≡ 99 mod 7 = 1

(3)若a≡b(mod m),且n∈N,     

        2 ≡ 7 mod 5 = 2, 4 ≡ 49 mod 5 = 4 , 8 ≡ 343 mod 5 = 3

(4)若a≡b(mod m),且k是整数,则k×a≡k×b(mod m);

        2 ≡ 7 mod 5 = 2, 4 ≡ 14 mod 5 = 4,6 ≡ 21 mod 5 = 1

(5)若a≡b(mod m),且m=qn,则a≡b(mod n)

        3 ≡ 15 mod 12 = 3, 12=3x4, 3 ≡ 15 mod 4 = 3, 3≡ 15 mod 3 = 0

        同余定理的目的不是捣鼓这些变换,而是解决问题:比如

Q1)求2的90次方 除以11的余数

红线标注部分,属于取模的一些性质,这些性质可以通过下面的例子看出:

4 mod 11 = 4,有 (4+11) mod 11 = 4,也有 (4 - 11)mod 11 = 4 也就是任何一个数加减n倍的mod的 余数不变,类似钟表6点钟,转一圈还是回到6点,不管是正转还是反转,也不管是转多少圈。

Q2)求1992×59除于7的余数

13 mod 7 = 6 ,有 (1*7 + 6) mod 7 也等于6

9 mod 7 = 2,有(1*7 + 2) mod 7 也等于2

13x9 mod 7 = 117 mod 7 = 5

(1*7+6) x (1*7+2) mod 7 = 2*6 mod 7 = 12 mod 7 = 5

所以,1992x59 mod 7 = (1992%7) x (59%7) mod 7 = 4x3 mod 7 = 12 mod 7 = 5

或者,可以这样理解,1992x59 mod 7 = (284*7+4)x(7*8+3) mod 7 = 4x3 mod 7 = 5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下家山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值