计算机底层都是存储数据都是采用二进制,但二进制也有几种,比如:原码、反码、补码。接下来我们来看看他们之间的关系的意义作用。
原码
十进制数按照:除二取余、倒序排列,得到的就是原码。
- 10 -> 0000 1010
- -10 -> 1000 1010
- -1 -> 1000 0001
- 1 -> 0000 0001
问题
原码在做计算的时候会出现一些问题,比如正负数的加法运算,以及零的问题。
- 正负数加法
- -1 + 1 = 0
1000 0001
+ 0000 0001
----------------
1000 0010 -> -2 ?
- 正负零
- +0 和 -0
- 十进制数字0,占了两个二进制;
0000 0000
1000 0000
反码
为了解决上面的问题,出现了反码,反码的计算规则如下:
- 正数的反码就是原码本身;
- 负数的反码是按位取反(但符号位不变);
示例
● 1 -> 0000 0001 -> 0000 0001
● -1 -> 1000 0001 -> 1111 1110
1111 1111 是运算完之后的结果,但要注意,这时还是反码,需要重新返回来:1000 0000 。
反码解决了正负数加法问题,但正负零的问题还是存在。
补码
正数的补码就是原码本身;
负数的补码就是在反码的基础上+1;
- 1 -> 0000 0001 -> 0000 0001 -> 0000 0001
- -1 -> 1000 0001 -> 1111 1110 -> 1111 1111
0000 0001
+ 1111 1111
----------------
0000 0000
补码在正负数加减法运算时没问题,也不会出现正负零占两个二进制。但 1000 0000 不表示为负零,用来表示什么呢?计算机其实默认把8位有符号二进制 1000 0000 表示为 -128 。
int8_t e = 0b10000000;
printf("%d\n", e);