补码是反码加一
正数的原码反码补码都相同
unsigned char 在计算机中使用补码储存
int/unsigned int变量赋值给 unsigned char变量是会发生字节截断(9位和高于9位的将被程序自动丢弃)
负数以补码形式储存
signed char 溢出的表示
我们也已经知道了signed char的取值范围是:-128~127.
关于上界溢出
十进制 二进制 值
126 0..0 0111 1110 126
127 0..0 0111 1111 127
128 1..1 1000 0000 -128
129 1..1 1000 0001 -127
关于下界溢出
十进制 二进制(补码形式) 值
-127 1..1 1000 0001 -127
-128 1..1 1000 0000 -128
-129 0..0 0111 1111 127
-130 0..0 0111 1110 126
注:0..0 表示24个0,1..1表示24个1
3.解析
从上述两个表格中可以看到,不管是否超过上下届,不管是负数还是正数,每增加(减少)一个单位,就直接在二进制表示的最后一位上加(减)1个单位。
并且相加和相减时,都先不看前24位,如果倒数第8位变为1,则前面24位全部设置为1,该数被解释为负数;如果倒数第8位变为0,则前面24位全部设置为0,该数被解释为正数。
(1)126和127
126和127是范围之内的数字,他们的值是遵从规则的。所以他们的值也是126和127,并没有越界。
(2)128
从程序实验和上表的结论中,我们得出了128的值竟然是-128.128这个数字是越界的数字,是127+1。
这时会在127的最后8位上加1,也就是在0..0 0111 1111的后8位0111 1111上加1,变为1000 0000。倒数第8位变成了1,所以前24个位也全部变为1,所以该数被表示为负数。它的值为 -1*2^7+0=-128。
根据负数的值在计算机中是以补码的形式存储的理论,也就是说1000 0000是补码,即:-128在计算机中是以1000 0000存储的,-128的原码是1000 0000(补码)减1,再取反,结果还是1000 0000(原码)。
(3)129
129和128的取值也是一样的道理。129是127+2或者128+1,抛开前24位不说,它的二进制为1000 0001,倒数第8位为1,所以前24位也为1,并且为负数。所以它的值表示为: -1*2^7+1=-127.
根据负数的值在计算机中是以补码的形式存储的理论,1000 0001是补码,即:-127在计算机中是以1000 0001存储的,-127的原码是1000 0001(补码)减1,再取反,结果是0111 1111(原码)。
(4)-127和-128
这两个数字都是在范围之内 没有什么可说的了吧,并且它们的二进制形式也刚刚讲过了。
(5)-129
-129是-128-1所得,所以-128的最后8位是1000 0000,减去1变为0111 1111,前面24位全部置位0,且该数被解释为正数,其值为2^0+2^1+2^2+2^3+2^4+2^5+2^6=2^7-1=127
(6)-130
-127的最后8位是1000 0001,减去3变为0111 1110,前面24位全部保持0,且该数被解释为正数,其值为2^1+2^2+2^3+2^4+2^5+2^61=126
unsigned char 溢出的表示
范围是0~255
关于上界溢出
十进制 | 二进制 | 值 |
254 | 0..0 1111 1110 | 254 |
255 | 0..0 1111 1111 | 255 |
256 | 0..0 0000 0001 | 0 |
257 | 0..0 0000 0001 | 1 |
关于下界溢出
十进制 | 二进制 | 值 |
2 | 0..0 0000 0010 | 2 |
1 | 0..0 0000 0001 | 1 |
0 | 0..0 0000 0000 | 0 |
-1 | 0..0 1111 1111 | 255 |
-2 | 0..0 1111 1110 | 254 |
注:0..0 表示24个0,1..1表示24个1
其实和有符号基本相同,唯一的差别就是,前面的24位一直都是0,并且该数永远都是正数。
比如256,256=255+1所得,255为0..0 1111 1111,然后加1,虽然255的全码都是1,再加1貌似没法加了,但是我们仍可将1111 1111前面一位加1,最后得到0001 0000 0000,之后我们就只看后8位即可,所以256的值是0.
比如-1,-1=0-1所得,0000 0000减1相当于减去0000 0001,虽然0的全码是0…0 0000 0000,似乎往上也没法借位,但是我们仍可将0000 0000前面一位加上1,看做0001 0000 0000减去0000 0000 0001,最后得到0000 1111 1111,我们直接取最后8为即可。