【无符号数】 一个字节有8位,如果全部用来表示数值,一共可以表示 2^8=256
个数 0,1,2,3,...,255
【有符号数】 如果用最高位表示符号(0表示正,1表示负),那么只剩下7位表示数值:
"0000 0001" ~ "0111 1111"
表示127个正数"1000 0001" ~ "1111 1111"
表示127个负数"0000 0000"
和 "1000 0000"
未表示任何数,由于平时+0
等于0
,于是规定
"0000 0000"
表示 0"1000 0000"
可以表示一个数(肯定不能是-0
吧),显然应该是一个负数,而 -1 ~ -127
都已经表示了,所以用"1000 0000"
表示 -128-128~127
共256个数注:以上二进制不是反码也不是补码,均为原码
首先注意几点:
正数以及0的原码、反码、补码相同,就不多说了
将负数的【原码转为补码】,需要经历几个步骤:
假设一个8位类型的数字 -1
:
1000 0001
1111 1110
+1
,如-1的补码:1111 1111
将负数的【补码转为原码】,只需要记住:"补码的补码==>原码",也就是通过计算补码的补码即可还原出原码。
如:-1的补码
1111 1111
---[符号位不变,其余取反]--->1000 0000
---[+1]--->1000 0001
下图来源于维基百科,是几个特殊的数字的补码
前面说过,在计算机内部,数字的存储、运算都是以补码形式进行
那么 "127+1"的运算过程如下
127 的补码是: 0111 1111
1的补码是: 0000 0001
相加后的补码: 1000 0000
(补码运算时,符号位也参与运算)
然后,要把补码转换为人方便阅读的原码:
根据最前面说到的结论可知,1000 0000(原码)
不表示 -0
而表示 -128
同理,"127+2"的运算步骤:
- 127 的补码是:
0111 1111
- 2的补码是:
0000 0010
- 相加后的补码:
1000 0001
(补码运算时,符号位也参与运算)- 相加结果转为原码:
1000 0001(补码)
--->1111 1110(反码)
--->1111 1111(原码)=-127
#include <stdio.h> int main() { char a=127, b=127; a+=1; b+=2; printf("计算结果:%d ,%d\n", a, b); // 输出: 计算结果:-128 ,-127 return 0; }
去菜鸟工具验证