原码,反码,补码[转]文章分类:C++编程[转载]http://shychj-chjshy.blog.sohu.com/73142224.html
1、原码、反码和补码的表示方法 (1) 原码:在数值前直接加一符号位的表示法。 例如: 符号位 数值位 [+7]原= 0 0000111 B [-7]原= 1 0000111 B 注意:a. 数0的原码有两种形式: [+0]原=00000000B [-0]原=10000000B b. 8位二进制原码的表示范围:-127~+127 (2)反码: 正数:正数的反码与原码相同。 负数:负数的反码,符号位为“1”,数值部分按位取反。 例如: 符号位 数值位 [+7]反= 0 0000111 B [-7]反= 1 1111000 B 注意:a. 数0的反码也有两种形式,即 [+0]反=00000000B [- 0]反=11111111B b. 8位二进制反码的表示范围:-127~+127 (3)补码的表示方法 12)补码的表示: 正数:正数的补码和原码相同。 负数:负数的补码则是符号位为“1”,数值部分按位取反后再在末位(最低位)加1。也就是“反码+1”。 例如: 符号位 数值位 [+7]补= 0 0000111 B [-7]补= 1 1111001 B 补码在微型机中是一种重要的编码形式,请注意: a. 采用补码后,可以方便地将减法运算转化成加法运算,运算过程得到简化。正数的补码即是它所表示的数的真值,而负数的补码的数值部份却不是它所表示的数的真值。采用补码进行运算,所得结果仍为补码。 b. 与原码、反码不同,数值0的补码只有一个,即 [0]补=00000000B。 c. 若字长为8位,则补码所表示的范围为-128~+127;进行补码运算时,应注意所得结果不应超过补码所能表示数的范围。 2.原码、反码和补码之间的转换 由于正数的原码、补码、反码表示方法均相同,不需转换。 在此,仅以负数情况分析。 (1) 已知原码,求补码。 例:已知某数X的原码为10110100B,试求X的补码和反码。 解:由[X]原=10110100B知,X为负数。求其反码时,符号位不变,数值部分按位求反;求其补码时,再在其反码的末位加1。 1 0 1 1 0 1 0 0 原码 1 1 0 0 1 0 1 1 反码,符号位不变,数值位取反 1 +1 1 1 0 0 1 1 0 0 补码 故:[X]补=11001100B,[X]反=11001011B。 (2) 已知补码,求原码。 分析:按照求负数补码的逆过程,数值部分应是最低位减1,然后取反。但是对二进制数来说,先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1 有方法。 例:已知某数X的补码11101110B,试求其原码。 解:由[X]补=11101110B知,X为负数。求其原码表示时,符号位不变,数值部分按位求反,再在末位加1。 1 1 1 0 1 1 1 0 补码 1 0 0 1 0 0 0 1 符号位不变,数值位取反 1 +1 1 0 0 1 0 0 1 0 原码 #include<stdio.h> void main() { short int tt = 65535 ; //unsigned short int tt = 0XFF43; printf("size of is %d\n",sizeof(tt)); printf("%0X\n",tt); printf("%d\n",tt); } 结果: size of is 2 FFFFFFFF -1 输出FFFFFFFF 是因为在第2个Printf,传递参数的时候,系统将Short int 自动转化为Int . #include<stdio.h> void main() { short int tt = -1 ; //unsigned short int tt = 0XFF43; printf("size of is %d\n",sizeof(tt)); printf("%0X\n",tt); printf("%u\n",(unsigned short int)tt); } 输出: size of is 2 FFFFFFFF 65535 ############################ int main(void) { unsigned int un = 3000000000; /* 我使用的编译器 int 是 32 位的 */ short end = 200; /* 而 short 是 16 位的 */ long big = 65537; printf("un = %u and not %d\n", un, un); printf("end = %hd and %d\n", end, end); printf("big = %ld and not %hd\n", big, big); printf("Press ENTER to quit..."); getchar(); return 0; } 程序输出结果如下: un = 3000000000 and not -1294967296 end = 200 and 200 big = 65537 and not 1 Press ENTER to quit... 这个程序表明,错误使用格式限定符会导致意想不到的输出。首先,错误使用 %d 来做无符号整型变量 un 的格式限定符,导致输出的是负数。这是因为我的计算机使用相同的二进制形式来表示 3000000000 和 -129496296 ,而计算机只认识二进制。所以,如果我们使用 %u 告诉 printf 输出无符号整数,输出的就是 3000000000;如果我们误用了 %d,那么输出的就是一个负数。不过,如果我们把代码中的 3000000000 改成 96 的话,输出就不会出现异常。因为 96 没有超出 int 的表示范围。 然后,对于第二个 printf,无论我们使用 %hd 还是 %d,输出的结果都是一样的。这是因为 C 语言标准规定,当 short 类型值传递给函数时,要自动转化成 int 类型值。之所以转化成 int,是因为 int 被设计为计算机处理效率最高的整数类型。所以,对于 short 和 int 大小不同的计算机来说,把变量 end 转化成 int 类型再传递给函数,速度更快。如此说来,h 好像没有存在意义。其实不然。我们可以用 %hd 来看看较大的整数类型被截断成 short 类型的时候会是什么样的。 而第三个 printf,由于误用 %hd,导致输出是 1。这是因为,如果 long 是 32 位的话,65537 的二进制形式便是 0000 0000 0000 0001 0000 0000 0000 0001,而 %hd 命令 printf 输出 short 类型的值,从而导致 printf 只处理 16 位数据(假设 short 是 16 位的),最终导致输出 1。 |
|