C语言 char 127+1 问题
一个字节能存下多大的整数
【无符号数】 一个字节有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"或"1", 都能参与运算。
- 而人要想认出这个计算结果到底是多少,就需要转化为原码才可以。
正数以及0的原码、反码、补码相同,就不多说了
负数补码与原码相互转换
将负数的【原码转为补码】,需要经历几个步骤:
假设一个8位类型的数字 -1
:
- 写出原码:符号位用1表示,如-1的原码:
1000 0001
- 写出反码:【符号位不变】,其余各位取反,如-1的反码:
1111 1110
- 计算补码:在反码的基础上
+1
,如-1的补码:1111 1111
将负数的【补码转为原码】,只需要记住:"补码的补码==>原码",也就是通过计算补码的补码即可还原出原码。
如:-1的补码
1111 1111
---[符号位不变,其余取反]--->1000 0000
---[+1]--->1000 0001
下图来源于维基百科,是几个特殊的数字的补码
【127+1】的运算
手算
前面说过,在计算机内部,数字的存储、运算都是以补码形式进行
那么 "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
C程序
#include <stdio.h>
int main()
{
char a=127, b=127;
a+=1;
b+=2;
printf("计算结果:%d ,%d\n", a, b); // 输出: 计算结果:-128 ,-127
return 0;
}
要点总结
- 正数以及0的原码、反码、补码相同
- 计算机存储和运算时使用【补码】,补码运算时,符号位也参与
- 负数的原码、反码、补码转换过程中,符号位不变;转换过程中,即使有进位,符号位也不参与运算
本文来自博客园,作者:aJream,转载请记得标明出处:https://www.cnblogs.com/ajream/p/16375196.html