有符号数与无符号数二进制数0…000003表示零,0…00001表示一,0…00010表示二,如此等等直到无限,但是负数怎么办?为了表示有符号数,大多数计算机系统使用二进制补码计数系统(two’s complement numbering system)。有符号数采用的表示法给这些数添加了一些基本的约束,因此,为了更有效地使用有符号数和无符号数,了解它们的表示法之间的区别是非常重要的。使用n位最多可以表示2n个不同的对象。负数有着和正数平等的地位,因此我们不得不将这2n个组合在负数与非负数之间“平分”。例如,一个字节可以表示负数-128 .. -1和非负数0 .. 127。而 16位的字则可以表示范围在-32,768 .. +32,767之间的有符号数。32位的双字可以表示范围在-2,147,483,648 .. +2,147,483,647之间的数。总之,使用n位可以表示范围在-2n-1到+2n-1-1之间的有符号数。二进制补码系统使用最高位作为符号位(sign bit)。如果最高位是零,则表示该数非负,如果最高位作是一,则表示是负数,以下是16位数的一些例子:$8000(%1000_0000_0000_0000)是负数,因为最高位是一$100(%0000_0001_0000_0000)是非负数,因为最高位是零$7FFF(%0111_1111_1111_1111)是非负数$FFFF(%1111_1111_1111_1111)是负数$FFF(%0000_1111_1111_1111)是非负数为了将一个二进制补码表示的数取负(negate),可以使用如下算法:1. 将该数的所有位取反(invert),也就是将所有的零改为一,所有的一改为零。2. 将取反后的数加一(忽略溢出)。例如,以下就是计算十进制数-5的8位表示的步骤:%0000_0101五 (二进制)%1111_1010所有位取反%1111_1011加一,得到�6�15 (二进制补码表示)现在对-5再取负,结果就是5(%0000_0101),正如我们所预期的一样:%1111_1011-5的二进制补码表示%0000_0100所有位取反%0000_0101加一,得到5 (二进制)以下举一些16位数和将它们取负的例子:首先,对32,767($7fff)取负:$7FFF:%0111_1111_1111_1111+32,767,最大的十六位正整数 %1000_0000_0000_0000所有位取反(8000h) %1000_0000_0000_0001加一(8001h,即是-32,767)接下来,对16,384($4000)取负$4000:%0100_0000_0000_000016,384 %1011_1111_1111_1111所有位取反($BFFF) %1100_0000_0000_0000加一($C000,即是-16,384)再对-32,768($8000)取负$8000:%1000_0000_0000_0000-32,768,最小的16位负整数 %0111_1111_1111_1111所有位取反($7FFF) %1000_0000_0000_0000加一($8000,即是-32,768)对$8000取反得到$7FFF,再加一得到$8000!等等,这是怎么回事?-(-32,768)还是-32,768?当然不是。但是,16位二进制补码计数系统是无法表示+32,768的。基本上,我们是不能对二进制补码计数系统中的最小值取负的。