signed、unsigned数值溢出分析

signed char类型为例:占1个字节 = 8 位                                                                       

1、范围:符号位占1位(正数为0,负数为1),剩下七位为数值位:

1 000 0000B ~ 0 111 1111B =》-128 ~ 127 =》-2^7 ~ 2^7-1(注意:-128)没有相对应的原码和反码,(-128) = (10000000)

                                                                                                                                                                                         

2、计算机储存都是以补码形式,正数的反码补码为本身,负数的反码为每位取反,补码为反码的末位加1

例如:

+127:0 111 1111B =反码》0 111 1111B =补码》0 111 1111B

 -127:1 111 1111B =反码》1 000 0000B = 补码》1 000 0001B

当+127+1 时:

127:0 111 1111B

    1:0 000 0001B

----------------------------相加

          1 000 0000B(符号为1,所以为负数,但是-128)没有相对应的原码和反码,(-128) = (10000000)

=》因此时间结果为 -128

128:0 1000 0000B(此时9位)实际内存只有八位,所以最高的0被截断,剩下一个signed char 内存大小的内容为:

1 000 0000B(补码) =  -128注意:-128)没有相对应的原码和反码,(-128) = (10000000))

当 -128 - 1 时:

-128:1 000 0000B(补码)

    -1: 1 111 1111B(补码)

--------------------------------------相加

             0 111 1111B(符号为0,所以为正数,正数补码为原码)

=》因此结果为 127

-129:1 1000 0001B(原码) =》1 0111 1110B(反码) =》1 0111 1111B(补码)(此时9位)实际内存只有八位,所以最高的1被截断,剩下一个signed char 内存大小的内容为:0 111 1111B(补码,符号位为0是正数,正数的原码为补码),0 111 1111B = 127

=》因此结果为 127

unsigned char类型为例:占1个字节 = 8 位                                                                       

范围:0000 0000B ~ 1111 1111B =》 0 ~ 2^8-1

当255 + 1时:

255: 1111 1111B

    1: 0000 0001B

---------------------------相加

           0000 0000B

=》因此结果为 0

256:1 0000 0000B(此时9位)unsigned char 占8位,因此1溢出被截断,剩下一个unsigned char 内存大小的内容为: 0000 0000B = 0

=》因此结果为 0

当0 - 1时:    

 0:0000 0000B(补码)

-1:1 111 1111B(补码)

-----------------------相加

       1 111 1111B(因为是unsigned char类型,所以无符号位,原码为补码)

=》因此结果为 255

-1:1 111 1111B(补码)(因为是unsigned char类型,所以无符号位,原码为补码)

1 111 1111B(补码) = 1 111 1111B(原码) = 255

=》因此结果为 255

补充:

signed int a = -20;

unsigned int b = 10;

b + a  <  6?printf("y"):printf("n")

答案为printf("n"),因为在比较时,a + b的结果是以补码形式的unsigned int 与6进行比较,a + b补码最高位为1,那得多大



你可能感兴趣的:(C语言)