分类: LINUX
2010-09-14 00:14:29
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
#include
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;
}