答案:有符号数与无符号数二进制数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 | 加一,得到?5 (二进制补码表示) |
现在对-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_0000 | 16,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的。基本上,我们是不能对二进制补码计数系统中的最小值取负的。
有符号就是signed:在存放整数的储存单元中,最左边的一位是表示符号位,该位为0,表示数值为正,1为负.
无符号就是unsigned:就是最左边的那一位没有符号位
上一个:用C语言编写计算器,最好可以有源代码。。以下是要求:
下一个:C语言程序 哪位高手帮忙找下错(简单的职工管理系统)