关于补码的计算

 今天用java写个程序中用这样的这一句代码

  int i=6;

   ~i;

结果~i 的值是 -7,有点不解,随即就有了下面一大堆的说明。

一看是负数,我就想到负数在计算机中都是以补码形式表示的。

大学时学的补码,好久不用现在计算方法都忘记的差不多了。那好,下面先复习一下补码。

 

什么事发生我们都要问为什么。那么计算机中为什么要用补码表示负数呢?

 

我们知道,计算机的计算核心cpu,由控制器与运算器组成,而这个运算器,在四则运算中,其实只会做加法运算,用加法来完成加,减,乘,除的。比如现在有操作数是负数,就意味着计算机要做减法,这个它是不会的,它只有用做加法来完成做减法的工作。这个要想通,怎么样,你这样想。

 

比如现在正确时间是下午17点,结果你的时钟时针已指向19点,现在你要做的就是让你的时针由19点指向17点来得出正确时间,常规做法就是逆拔你的时针2格,就是说减2来实现,但是还有一种方法,就是顺拔你的时针10格来实现,这样就是加10来实现,看到了吧,可以用加法来实现减法的。

 

下面说这个做法的理论支持:

 这里其实有个叫模的概念。比如表示小时这个计数系统中,,它的模就是12,即计数量是12个,用0-11表示,也即多于0-11这12种表示法时,计数系统又回到0这个表示法,比如11点一过,时针又指向0点。那么为什么刚才说的-2和+10,它们能完成相同的工作,因为它们有这样的一个特性2+10=12.即绝对值相加等于模。这样在这个计数系统中,2叫10的补数,同样10也叫2的补数,一句话它们是互补的。

然后我们把这个理论加以推广。计算机中加法器运算位数也是一定的,比如说是8位的。那当它到1111 1111(255)时,再加1就又变为0000 0000了,这就相当于上面说的0-11,而255相当于11,这个8位的计数系统的计数量是256个,即0到255。这里有下公式,即n位二进制计数系统中,模是2的n次方。

 

在这样一个8位计数系统中,比如先有一个操作数据是0,我们要得到32这个结果,根据上面的理论,我们可用0+32,或0+(-223)来完成,加32(0010 0000)很好理解即

00000000

0010 0000

——————

0010 0000=32;

那0+(-223)怎么来完成呢,这就牵涉出来一负数在计算机中的表示问题,

知识告诉我们负数在计算机中都是以其补码形式表示。

那么怎么求一数据的补码呢

规则

1,正数的,原码,反码,补码都是它本身,这是规定。死的。

2,负数的,原码:最高位是符号位,即1表示负,0表示正,当然就是1,后们是数值位。比如,-15,它的原码是

1              0001111

(符号位)(数据值位)

3,负数的反码表示为,在原码基础上,符号位不变,其余各位取反。还是-15,它的反码是

 

1              0001111

(符号位)(数据值位)

——————————

1              1110000  (反码)

3,负数的补码表示为反码在末位加1,还是-15它的补码是

 

1              1110000  

(符号位)(数据值位)

+                          1

——————————

1              1110001,

4,在位数一定的条件下,比如n位,补码表示的范围是 负的2的n减一次方到正的2的n减一次方再减一。

 

还有一常用的算法,我知道了怎么求一个数的补码,那看到一个补码,怎么知道它是什么数值的补码呢,

1,看到第一位是0,那它就是个正数据了,正数据的原码,反码,补码一样,直接运算就得值了。

2,看到第一位是1,说明它是个负数,那就,第一位,符号位不变,其余位按位取反,然后末位加1就行了。

比如。1000 1111.这个数是谁的补码呢,先取反,记得保留第一位,得1 111 0000,再加1,即 1 111,0001。

1 111,0001,这串数字就是原码了,原码怎么算,第一位,说明 它是负数,后面再算就会是64+32+16+1=113,即

 

1000 1111的是-113补码

 

好补码先说到这,接着那个上面要得到结果的32(0010 0000)的问题,得到32就要+(-224),那么我们求-224的补码,

我们先得到它的原码,由于补码的表示范围是 负的2的n减一次方到正的2的n减一次方减一,所以要表示-224我们要用最少要用9位二进制位表示,

原码是

1 1110 0000, 第一位是符号位

得出反码是 1 0001 1111

最后补码是 1 0010 0000

 

然后再和0相加,

0 0000 0000

1 0010 0000

————————

1 0010 0000

由于我们用到的模是256即8位的二进制,那么舍弃最高们就是0010 0000,即得32.

 

 

 

 

以上是复习了,补码的一些概念,现在我们来说说,为什么java中~6会是-7呢,

因为,java 中int,是4字节表示,int 6,在计算机中,应该是

 0000 0000 0000 0000 0000 0000 0000 0110 表示,用~各们取反后得

 1111 1111 1111 1111 1111 1111 1111 1001,那这么一串东西表示是什么数据呢,

 

 

利用以上的知识,我们知道最高位是1,那么它肯定是个负数,是负数我们就要求得其原码,才知道它到底是什么数值,因为你也知道,负数在计算机中,从来都不是以原来面目出现的,都是以补码形式。

求其原码,先符号位不变,按位取反,得到它的反码即 

 1000 0000 0000 0000 0000 0000 0000 0110

然后反码末位加1

 1000 0000 0000 0000 0000 0000 0000 0111得到它的真身,原码了,

怎样解读原码,知道吧

明显它就是-7。到这终于把-7给说明白了。

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值