c++系列文章(1):signed和unsigned

博客链接
  带符号类型(signed)可以表示正数、负数或0,无符号类型(unsigned)仅能表示大于等于0的值。C++标准并没有规定signed类型应该如何表示,但约定了在表示范围内正值和负值的量应该平衡。在计算机内部,signed类型二进制的最高位是符号位,用来表示正负,其余二进制位用来表示数值;unsigned类型的所有二进制位都用于表示数值。

类型 最小值 最小值 大小
char -128(-2^7) 127(2^7-1) 1字节
signed char -128(-2^7) 127(2^7-1) 1字节
unsigned char 0 255(2^8-1) 1字节
short -32768(-2^15) 32767(2^15-1) 2字节
unsigned char 0 65535(2^16-1) 2字节
int -2^31 2^31-1 4字节
unsigned int 0 2^32-1 4字节
long -2^63 2^63-1 8字节
unsigned long 0 2^64-1 8字节

signed的负数范围比正数范围多1

  为什么signed类型的负数范围总是比正数范围多一个,这是因为在计算机内部存储时并不是直接采用原码形式,而是采用补码的形式。下面以signed char为例进行说明。
  不使用原码,是因为计算机只会做加法,不会做减法,例如1-1在计算机内部使采用1+(-1)的形式进行计算的。如果直接采用原码计算得到的结果是-2,为了避免原码减法运算错误的问题,引入了反码正数的反码是其原码本身,负数的反码是其原码除符号位外全部取反
  但反码又会带来新的问题,-0和+0都表示0,+0的反码为00000000,-0的反码为11111111,但这两个不同的反码都表示0,为了避免出现两个0的表现形式,引入了补码正数的补码使其原码本身,负数的补码是其反码加1。此时+0的补码为0000 0000,-0的补码为1111 1111加1即1 0000 0000,由于signed char是8位,因此取低8位即为0000 0000,这样+0和-0的补码都是同一个形式。 但此时-0的原码1000 0000则没有作用了,而-128的原码1 1000 0000的低8位正好和-0的原码1000 0000相同,为了提供利用率,便用-0的原码来表示-128,cout << (int)((char)(0x80)); //输出-128

注意事项

  char和bool类型不用用于算术表达式,char类型在某些机器上表现为unsigned char,在另一些机器上表现为signed char(在本环境下表现为signed char),为了代码易移植,在使用char是最好明确是unsigned还是signed。
  赋给unsigned类型一个超出它范围的值时,结果是初始值对unsigned类型表示数值的总数取模后的余数,如unsigned char c = -1; //c的值是-1%256,即255
  赋给signed类型一个超出它范围的值时,结果是未定义的,在本环境下,signed char c = -130; //c的值是126signed char c = 129; //c的值是-127
  当表达式中既有unsigned类型又有signed类型时,signed类型都会转换成unsigned类型,因此不能将unsigned和singned类型在同一个表达式中混用。
  无论从unsigned类型中减去一个多大的值,最后的结果都不可能是负数。

发布了19 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/hjc132/article/details/103430160