1 计算机中数的二进制存储规则
1.1 案例分析
你能看懂以下的运算吗?如果暂时还不行,请往下读,让我们一起把二进制存储规则彻底搞明白。
#include <iostream>
using namespace std;
int main() {
int n = -100;
n = n >> 4;
cout << n << endl; // -7
n = n << 4;
cout << n << endl; // -128
int m = 5;
cout << ~m << endl; // -6
return 0;
}
1.2 规则总结
我们以正数和负数为界,理解计算机中的二进制存储规则:
- 第一点:正数的原码、反码、补码相同;
- 第二点:负数的反码,原码按位取反(符号位保持不变);负数的补码,反码 + 1;
- 第三点:
算术运算
,补码形式参与运算;读取时——原码形式读取; - 第四点:
左右移运算
,以补码形式参与运算,正数左右移、负数左移均以补 0 操作(符号位保持不变),负数右移以补 1 操作(符号位不变); - 第五点:
按位运算
,补码形式参与运算,符号位与数值位地位相同。
由此我们发现,运算均在补码的形式上进行,需要注意的点有负数右移以补 1 操作(符号位不变),按位运算时符号位与数值位地位相同,下文将重点分析上述两个注意点。
2 负数的右移运算
-100 带符号右移 4 位。
-100 原码: 10000000 00000000 00000000 01100100
-100 补码: 保证符号位不变,其余位置取反加 1
11111111 11111111 11111111 10011100
右移 4 位: 在高位补 1
11111111 11111111 11111111 11111001
补码形式的移位完成后,结果不是移位后的结果,要根据补码写出原码才是我们所求的结果。
其方法如下:
保留符号位,然后按位取反
10000000 00000000 00000000 00000110
然后加 1,即为所求数的原码:
10000000 00000000 00000000 00000111
所有结果为:-7
3 正数的取反运算
~5 的补码:
5 原码:00000000 00000000 00000000 00000101
5 补码:00000000 00000000 00000000 00000101
~5 补码:11111111 11111111 11111111 11111010
取反加 1 得到原码:10000000 00000000 00000000 00000110;// 或者减 1 再取反得原码
所得结果:-6
4 小结
验证答案,并把情况总结。