补码|有符号数和无符号数区别

在计算机中,数值类型分为整数型或实数型,其中整型又分为无符类型或有符类型,而实型则只有符类型。 字符类型也分为有符和无符类型。在程序中,用户可以自己定义是否需要一个非负整数;
用char来举例吧,char占一个字节,一个字节=8个二进制位,所以它可以表示2^8个数,也就是256个数。若想要表示正负号,一般需要一个位来标记,如取最高代表正负号,则有符号和无符号的数值最大值对比如下:

1 有符号:0111 1111 = 2^6+2^5+2^4+2^3+2^2+2^1+2^0= 127; ==> 范围是 -128 ~ 127 2 3 无符号:1111 1111 = 2^7+2^6+2^5+2^4+2^3+2^2+2^1+2^0 = 255;==> 范围是0~ 255

可以看出无符号数只有正数,没有负数,所以比如一个8位元可以储存的最大正数的个数是2的8次方也就是256.而有符号数,因为要兼容负数的可能性,就要牺牲一个位元来做符号表明.所以一个有符号数的最大正数的个数就是2的(8-1次方)再减掉1…是127.
我们可以在程序中直观的看一下他们之间的区别:
int main() { char c = 127; unsigned char u = 127; return 0; }

结果如下:
补码|有符号数和无符号数区别
文章图片
当取值大于127时,再看程序:
int main() { char c = 128; unsigned char u = 128; return 0; }

补码|有符号数和无符号数区别
文章图片

结果发生了变化,因为定义的c是有符号数,又因为c的表示范围是-128~127,所以当赋值c为128超过他的表示范围是,显示的值变为-128,有个小技巧,即128-256=-128,,若赋值-129,超过了其负数表示范围,就变成了-129+256=127,程序验证:
int main() { char c = -129; unsigned char u = -129; return 0; }

补码|有符号数和无符号数区别
文章图片

还有一个问题就是溢出的问题,char是个8位的二进制数,若超过了八位,就只算其16进制的末尾的两位的大小。比如unsigned char的表示范围是0x00~0xFF,若表示0x8FF,则溢出,指标是后两位,即FF,8忽略掉,程序验证:
int main() { char c = 0x8ff; unsigned char u = 0x8ff; return 0; }

【补码|有符号数和无符号数区别】补码|有符号数和无符号数区别
文章图片

    推荐阅读