关于二进制的负数怎么表示与移位运算

    对于正数的二进制,应该没有疑问,比如(以8位系统来分析,第一位为符号位)1的二进制表示为00000001。

    而对于负数来说,就比较麻烦,比如-1。有人说是10000001,而有人说是11111111。

    其实这两种说法都没错,这是分类方法的差异。在一些把二进制分为原码、反码、补码的体系中(注:当然对于正数,三码为1),10000001是-1的原码,而11111111是-1的补码。

    因为在计算机内,-1是以11111111(也就是上文的补码)的形式存储在计算机,同时计算机也是以补码的方式进行运算,所以有些人就不过原码反码补码这种乱七八糟的东西,直接认为-1就是1111111。

    题外话,为什么计算机存储负数的方式是采用补码,而不是采用原码(原码更有逻辑性)?还是以-1为例(如果要推导全部,请百度,由于比较复杂,这里就不推论了,,,因为我也不会。。)

    因为为了满足1-1=1+(-1)这个关系。

    如果采用原码,则1-1  != 1+(-1)= 00000001+10000001= 10000010=-2(原码表示)。

    而采用补码 ,则1-1 = 1+(-1) = 00000001+11111111 = 0(因为第8位溢出,相当于被丢弃),完美解决问题,别的负数也是符合这种机制,故为了运算方便,就舍弃了逻辑性。

    下面就来说一种我认为比较好的一种求负数的二进制(这里说的是补码)的方法。

    求一个负数的补码,我们只要用该负数的绝对值,取反加1就可以得到相应的负数。还是以-1为例,其绝对值是1,也就是二进制的00000001,取反加1得11111111,也就是-1的补码形式。

    而怎样从一个二进制数(补码)推出它的十进制数呢,(对于有符号数而言)首先看二进制的最高位,如果是0,则该二进制就是正数,这个很方便转换。若是1,则说明该二进制数是负数,但是补码的非逻辑性则使人很难看出这个数到底是多少,我们可以对这个数取反加一,那我们就可以得到这个数的二进制的绝对值,再由符号位就可以知道这个数的值了

    以11111111(补码)为例,最高位为1,我们知道它是负数,取反加1后,我们得到00000001,则知道其的绝对值是1,那么我们可以知道这个数就是-1。

你可能感兴趣的:(C语言学习篇)