补码

一个对象在计算机内部到底用哪些二进制代码表示,我们称之为编码。而补码的出现就是为了解决整数的存储问题。那到底什么是补码呢?

以8位的数据为例,对于无符号数来说是从00000000b~11111111b到0~255一一对应的。那么如何对有符号数进行编码呢?(即如何用8位数据表示有符号数)

--------------------------------------------------------------------------------------------------------------------------

【原码】:用数据的最高位来表示符号,1表示负,0表示正,其它位表示数值。

  例如:

  00000000b: 0       10000000b: 0

  00000001b: 1       10000001b: -1

  00000010b: 2       10000010b: -2

  01111111b: 127     11111111b: -127

如上的原码表示方法,简单易懂,但是0的表示不唯一,所以原码不能正确地表示有符号数。

---------------------------------------------------------------------------------------------------------------------------

【反码】:这种思想是,先确定用00000000b~01111111b表示0~127,然后用按位取反后的数据表示负数。

  例如:

  00000000b: 0       11111111b: 0

  00000001b: 1       11111110b: -1

  00000010b: 2       11111101b: -2

  01111111b: 127       10000000b: -127

如上的反码表示方法,同样存在0的表示不唯一的问题。

----------------------------------------------------------------------------------------------------------------------------

【补码】:这种思想是,先确定用00000000b~01111111b表示0~127,然后用按位取反加1后的数据表示负数(即先求反码后加1)。

  例如:
  00000000b: 0       11111111b + 1 = 00000000b: 0

  00000001b: 1       11111110b + 1 = 11111111b: -1

  00000010b: 2       11111101b + 1 = 11111110b: -2

  01111111b: 127       10000000b + 1 = 10000001b: -127

如上的补码表示方法,很好地解决了0重码问题。

在补码中:(1)最高位为0,表明是正整数;最高位为1,表明是负整数;

     (2)正数的补码取反加1所得为其对应负数的补码;负数的补码取反加1后,为其绝对值。

 

我们学习补码主要闹明白两个问题

(1)已知十进制数转二进制

  a.正整数转二进制:除2取余,直到商为0,将余数倒叙排列后得到二进制表示;

  b.负整数转二进制:先求与该负数对应的正整数的二进制代码,然后所有位取反加1;

  c.0转二进制:全为0。

举例:定义一个int类型的变量data=-20,求其补码?(这里int类型的长度为4byte)

正整数20的二进制表示为0000 0000 0000 0000 0000 0000 0001 0100,取反末尾加1后为1111 1111 1111 1111 1111 1111 1110 1100,十六进制表示为FFFFFFEC。Code::Blocks中验证结果如下:

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     int data = -20;
 6 
 7     printf("0X%X\n", data);
 8 
 9     return 0;
10 }
11 /*
12 The output results in Code::Blocks 10.05
13 -------------------------------------------------------
14 0XFFFFFFEC
15 
16 Process returned 0 (0x0)   execution time : 0.015 s
17 Press any key to continue.
18 -------------------------------------------------------
19 */

 

(2)已知二进制转十进制

  a.若首位是0,表明是正整数,按普通方法来求;

  b.若首位是1,表明是负整数,将所有位取反后末尾加1,得到该负数的绝对值。

举例:已知一个整数为0XFFFFFFFF,求对应的十进制?

0XFFFFFFFF的首位为1,所以是负整数,将所有位取反后得到0X00000000,加1后得到该负数的绝对值为0x00000001,所以FFFFFFFF对应的十进制数为-1。Code::Blocks中验证结果如下:

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     printf("%d\n", 0XFFFFFFFF);
 6 
 7     return 0;
 8 }
 9 /*
10 The output results in Code::Blocks 10.05
11 -------------------------------------------------------
12 -1
13 
14 Process returned 0 (0x0)   execution time : 0.018 s
15 Press any key to continue.
16 -------------------------------------------------------
17 */

 

posted @ 2013-09-28 21:25  unfickleness  阅读(397)  评论(0编辑  收藏  举报