定义一个char类型的变量 a , b,给它们赋予整形数值,如:
#include <stdio.h>
int main()
{
char a = 5;
char b = 126;
char c = a + b;
printf("%d", c);
return 0;
}
int 类型的变量拥有 32 个比特位,char 类型只能存放 8 个比特位,所以在 a 这里存放的是截取 5 的补码的从右开始选取的 8 个比特位。
在这里 5 的二进制序列补码为 0000 0000 0000 0000 0000 0000 0000 0101
char 类型的 a 只能存放 8 个比特位,所以从最右边开始截取 8 个比特位放入变量 a 当中,所以 a 存放的补码为 0000 0101,这时,将这 8 个比特位的最左边那位当成是符号位,0 为整数,1 为负数,以此来判定整数提升之后的符号位,并以此来补全剩下的比特位。即如果是 0 则在这 8 个比特位之前用 0 补齐剩下的 24 个比特位(32减8),如果是 1 则用 1 取补齐。
同理,126 的二进制序列补码为 0000 0000 0000 0000 0000 0000 0111 1110,b 存放的补码为(从最右边开始截取 8 个比特位): 0111 1110
现,要进行 a + b 就是将截取的两个 8 个比特位整形提升,提升为 32 个比特位的 int 类型再相加。
即:
0000 0000 0000 0000 0000 0000 0000 0101 ——> a 整形提升(一开始 a 存放的 8 个比特位的最左边为 0 ,表示正数,所以整形提升之后的 32 个比特位最左边也是 0 ,代表正数,并以 0 补齐,如果是负数,一开始 a 存放的 8 个比特位的最左边是 1 整形提升之后的 32 个比特位最左边也是 1 ,并以 1 补齐,如:-5,则一开始 a 存放的 8 个比特位为 1000 0101,整形提升之后为 1111 1111 1111 1111 1111 1111 1000 0101,b 同理)
0000 0000 0000 0000 0000 0000 0111 1110 ——> b 整形提升
将两个整形提升之后的补码参与运算,结果为:0000 0000 0000 0000 0000 0000 1000 0011,此为补码从最右边开始截取 8 个比特位存入 c 当中(因为 c 也是 char 类型的变量,只能存放 8 个比特位),即:1000 0011,因为要将c的结果以%d(整数)的形式打印出来,而 c 是 char 类型,所以要进行整形提升,结果为:1111 1111 1111 1111 1111 1111 1000 0011,减一变反码 1111 1111 1111 1111 1111 1111 1000 0010,取反变原码 1000 0000 0000 0000 0000 0000 0111 1101 ——> -125
简单的来说是这样的:
#include <stdio.h>
int main()
{
char a = 5;
//a -> 0000 0101(截取 5 的 32 个比特位中的 8 个比特位)
char b = 126;
//b -> 0111 1110(截取 126 的 32 个比特位中的 8 个比特位)
char c = a + b;// c = 0000 0101 + 0111 1110
//c 整形提升:1111 1111 1111 1111 1111 1111 1000 0011
//转换为原码 -> 1000 0000 0000 0000 0000 0000 0111 1101
printf("%d", c);//所以值为-125
return 0;
}