整数在计算机的内部是怎么表达的呢?计算机内部一切都是二进制.不管你是整数还是浮点数,最终他们都是二进制的东西,只是说我们以什么方式去看待它.如在计算机内部,18被表示为00010010,0被表示为00000000.那么-18呢?
- 十进制用"-"来表示负数,在做计算的时候.
我们在运算的时候总是把负号抛掉,变成两个正整数做运算,在得出运算结果后再去设法处理负号的问题.
那二进制应该怎么做呢?我们先要知道,一个字节可以表达的数的范围:00000000-11111111(0-255).然后有以下三种方案:
- 仿照十进制,有一个特殊的标志表示负数.这个标志是在8个比特以外的,比如说一个比特,这个比特如果是1就表示是正数,如果是0就表示负数,或者反过来都可以.反正我们有一个特殊的标志,说这个数是正的还是负的.
- 取中间的数为0,如1000000为0,比它大的数是正数,比它小的数是负数.
- 补码
但是前两种方案都存在问题.第一种方案就意味着我们的计算机对二进制数进行运算的时候,我们要像做十进制运算一样需要特别去判断这个标志.如000000001(负数)和00000001做加法,你就不能直接把这两个数当二进制相加,而是通过这个0把+转化为-,这样子的话在计算机的内部设计上就会比较复杂.更复杂的乘法和除法自然不用赘言.
第二种方案,如果采用中间数的话,那么10000000表达的就是0,当我们把这个二进制数翻译成十进制时,它原本是128.那我们在所有程序输入输出的地方都需要让它对这个128做减法,比如说你现在得到了10000001,实际上这个数是129了,如果按照这种表示法,得让他减去10000000,你实际上是1.那也会让我们的程序在输入输出过程中做的比较复杂.
实际上,我们在计算机中是怎么做的呢.我们可以考虑刚才那个-1.如果我们希望-1+1->0,如何能做到?
- 0->00000000
- 1->00000001
也就是说,我们希望有个东西加上1的这一长串会变成零.那么什么东西加上它会等于0呢?就是全1那个东西----11111111
- 11111111+00000001->100000000
而如果我们是8个比特的数,这多出来的1会丢掉,得出来的结果就是00000000.所以如果我们让00000001等于1,11111111等于-1,那么他们相加的结果就是0了.或者我们也可以换个角度想.0-1->-1,如果我们在0的前面加上一个1,即(1)00000000-00000001->11111111.实际上,我们把11111111当作纯二进制看待的话,它是255;而如果把它当作补码看待的话,它是-1.同理,对于-a来说,其补码就是0-a,实际是2^n-a,n是这种类型的位数.如100000000实际上是256,也就是2的8次方减去1就得到了-1的哪个补码.
在计算机内部,补码的意义是拿补码和原码相加可以得到一个溢出的0.补码最大的好处在于,如果你有了一个补码,你用这个补码来表示-1,那么当你在做运算的时候,你不需要根据条件去变换,把+变成-,把-变成+,直接拿他去做二进制的运算,你就可以得到你想要的结果.