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