unsigned int a = 0;
unsigned int b = -1; // b 为 0xffffffff
unsigned int c = a - 1; // c 为 0xffffffff
-
注意:printf 的 %d 会按有符号数进行输出;
printf("%d\n", (unsigned int)(0)-1); // -1 cout << (unsigned int)(0)-1 << endl; // 4294967295 cout << hex << (unsigned int)(0)-1 << endl; // ffffffff
0. 补码
- 对于负数
- 补码:反码+1;
- 反码:补码-1,再取反;
- 以 32 位有符号数负数的补码为例:
- -1:0xffffffff
1. 有符号位的正零与负零
-
32 位有符号数:-0 也即 0x80000000,表示32位有符号数最大的负数,也即 -2147483648(== 0x7fffffff + 1)
int x = 0x80000000; cout << x << endl; // -2147483648 int y = 0x7fffffff; cout << y+1 << endl; // -2147483648
0x8000 0000 == 0x7fff ffff + 1
2. 有符号位无符号位的移位运算
有符号数无符号数的左移均是逻辑移位,不会考虑符号位。无符号数右移,最左补零,有符号右移,保持符号位。
-
无符号位:
- 左移:最右补零;
- 右移:最左补零;
unsigned int x = 0xffffffff; cout << hex << (x << 1) << endl; // fffffffe cout << hex << (x >> 1) << endl; // 7fffffff
-
有符号位:
- 正数:
- 左移:第二位成为新符号位,有可能变为负数;
- 右移:左边补零,保持符号位;
- 负数
- 左移:第二位成为新符号位,有可能变为正数;
- 右移:左边补一,保持符号位;
int x = 0xa0000000; cout << hex << (x << 1) << "\t" << dec << (x<<1) << endl; // 40000000 1073741824,有符号位左移,第二位0成为新的符号位,负数变为正数 cout << hex << (x >> 1) << "\t" << dec << (x>>1) << endl; // d0000000 -805306368,有符号位右移,左端补1,保持符号位不变;
- 正数: