二进制补码及与移位 1、在计算机系统中,数值一律用补码来表示(存储)。 主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。 2、补码与原码的转换过程几乎是相同的。 数值的补码表示也分两种情况: (1)正数的补码:与原码相同。 例如,+9的补码是00001001。 (2)负数的补码:符号位为1,其余位为该数绝对值的原码按位取反;然后整个数加1。 例如,-7的补码:因为是负数,则符号位为“1”,整个为10000111;其余7位为-7的绝对值+7的原码0000111按位取反为1111000;再加1,所以-7的补码是11111001。FFFFFFFF=-1.32位机中int数字2补码表示: 4个字节,高位在前(在Intel体系中实际是按低字节在前的方式存储的) x=Sabcdefg hijklmno pqrstuvw xyzABCDE S为符号位,0为正1为负。-x = ~x+1 ; 如1 = 00000000 0000000 0000000 00000001,则-1 = ~(00000000 0000000 0000000 0000001)+1 = 1111111 11111111 11111111 11111110 + 1 = 1111111 1111111 1111111 1111111 左移位N位时将各数位依次前移N位,超过左边部分丢弃,右N位补0。如左移3位后的结果是: x < < 3 = cdefghij klmnopqr stuvwxyz ABCDE000 右移位N位时将各数位依次右移N位,超过右边部分丢弃,符号位保持不变。右移3位后的结果: x > > 3 = SSSSabcd efghijkl mnopqrst uvwxyzAB 当x是无符号数时,左移位规则与带符号移位规则相同,右移时符号位补0。无符号右移3位的结果: ((unsigned int)x) > > 3 = 000Sabcd efghijkl mnopqrst uvwxyzAB 对无符号数来说,左移N位相当于乘2的N次方,右移N位相当于除2的N次方。 但对带符号数则不能以此论之。#include <stdio.h>#include <limits.h>int main(){ //无符号整数范围0~2^32-1 unsigned int a= (2<<32)-1; //有符号整数范围-(2^31-1) -- (2^31-1) //最小:1000 0000 0000 0000 0000 0000 0000 0000 (B) = -2147483648 //最大:0111 1111 1111 1111 1111 1111 1111 1111 (B) = 2147483647 //int b= 0xFFFFFFF9; int b= 0xFFFFFFF6; //无符号整数相加超出范围,自动截断,所以不存在溢出 //-10= 1000 0000 0000 1010 //取反:1111 1111 1111 0101 //+1: 1111 1111 1111 0110=FFFFFFFF6 //FFFFFFFF6 //取反: 1000 0000 0000 1001 //+1 : 1000 0000 0000 1010 //所以得到: 1111 1111 1111 0110实际存储 <--取反+1-->表示(补码)1000 0000 0000 1010 printf("a->[%u] a+1->[%u] a+2->[%u]/n", a, a+1, a+2); int c = (b << 31) + 1; printf("b->[%d]/n", b); return 0;}