zoukankan      html  css  js  c++  java
  • 有(无)符号char型及其溢出问题

    转载自:http://blog.sina.com.cn/s/blog_70ec9a6f01014j1h.html

    1char的有无符号类型

    char 分为有符号性(signed)和无符号型(unsigned)两种:

    Ø         若是signed型,就意味着取值范围为[-128,127];

    Ø         若是unsigned型,就意味着取值范围为[0,255];

    C语言中我们通常直接用类型char,但是它究竟是被当做signed型还是unsigned型,由编译器决定。

    C语言允许我们在char前面加上关键字signed或者unsigned,这样,无论在编译器中被当做signed还是unsigned,都会按照前面加的这个关键字来决定。

    例如:假设我们现在使用的编译器,把char当做signed来看到,则

    char c1;

    signed c2;

    unsigned c3;

    c1和c2的取值范围都是[-128,127],而c3的取值范围则是[0,255]。

    所谓取值范围,是指其值在这个范围之内时,会被正确处理,超出这个范围就会发生溢出。但在这个范围之内,并不意味着它就是可打印字符。这点不要混淆。

     

    2、溢出

    1)有符号

    c1和c2一样,我们以c1为例来说明。先看向上超过上界的情况:

    十进制

    十六进制

    二进制

    126

    0000007e

    0…0 0111 1110

    126

    127

    0000007f

    0…0 0111 1111

    127

    128

    ffffff80

    1…1 1000 0000

    -128

    129

    ffffff81

    1…1 1000 0001

    -127

    130

    ffffff82

    1…1 1000 0010

    -126

    注:0…0表示24个0,1…1表示24个1

     

    十进制

    十六进制

    二进制

    -127

    ffffff81

    1…1 1000 0001

    127

    -128

    ffffff80

    1…1 1000 0000

    -128

    -129

    0000007f

    0…0 0111 1111

    127

    -130

    0000007e

    0…0 0111 1110

    126

    -131

    0000007d

    0…0 0111 1101

    125

    -256

    00000000

    0…0 0000 0000

    0

    -257

    ffffffff

    1…1 1111 1111

    -1

     

    从这两个表中可以看到,不管是否超过上下届也,不管是负数还是正数,每增加(减少)一个单位,就直接在二进制表示的最后一位上加(减)1。

    相加或相减时,都可以先不看前24位:如果倒数第8位变为1,则前面24位全部设置为1,该数被解释为负数;如果倒数第8位变为0,则前面24位全部设置为0,该数被解释为正数。下面我们挑几个例子详细说明:

    c1=128;

    这时,会在127的最后8位上加1,原来的8位是0111 1111,加1后,变为1000 0000,于是把前面24个位也全部变为1,且该数被表示为负数。其值为-1*2^7+0=-128.

    c1=129;

    128的最后8位是1000 0000,加上后为1000 0001,前面24位保持1不变。该数被解释为负数,其值为-1*2^7+1=-127.

    c1=-129;

    -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

    c1=-130;

    -127的最后8位是0111 1111,减去1变为0111 1110,前面24位全部保持0,且该数被解释为正数,其值为2^1+2^2+2^3+2^4+2^5+2^61=126

    c1=-257;

    由前面可以类推, -256的最后8位编码是0000 0000,减去1后变为1111 1111,前面24为全部置为1,该数被解释为负数,值为-1*2^7+2^0+2^1+2^2+2^3+2^4+2^5+2^6=-1。

    注意:0000 0000减去1,也就是减去0000 0001,单看这8位的话,前面的数较小,我们可以想象在前面那个数的前面再加一个1,变成0001 0000 0000,后面那个数前面加0,变成0000 0000 0000,相减后,我们只看最后8位即可。

     

    2)无符号

    我们以c3为例进行说明。

    十进制

    十六进制

    二进制

    254

    000000fe

    0…0 1111 1110

    254

    255

    000000ff

    0…0 1111 1111

    255

    256

    00000000

    0…0 0000 0000

    0

    257

    00000001

    0…0 0000 0001

    1

    258

    00000002

    0…0 0000 0010

    2

     

    十进制

    十六进制

    二进制

    -2

    0000007e

    0…0 1111 1110

    254

    -1

    0000007f

    0…0 1111 1111

    255

    0

    ffffff80

    0…0 0000 0000

    0

    1

    ffffff81

    0…0 0000 0001

    1

    2

    ffffff82

    0…0 0000 0010

    2

     

    其实和有符号型基本相同,唯一的差别就是,前面24位一直都置位0,且该数永远被解释为整数。下面举例说明:

    c3=256;

    因为255的最后8位是1111 1111,加1后变为0000 0000,所以其值为0;

    c3=-1;

    因为0的最后8位是0000 0000,减1后变为1111 1111,所以其值为255;

     

    0000 0000减1,相当于减去0000 0001,虽然0的全码是0…0 0000 0000,似乎往上也没法借位,但是我们仍可将0000 0000前面一位加上1,看做0001 0000 0000减去0000 0000 0001,最后得到0000 1111 1111,我们直接去最后8为即可。

     

    归纳:不管是有符号还是无符号,在前面的数小于后面的数时,都可假设在前面的数的上一位加1,而后面的数前面加0,从而进行相减;

    另外,相加时,如果最高位,即倒数第8位变为0,只需直接将其变为0即可,其它位不变,不需要进位。

    对于无符号型,前24位永远为0,对于有符号型,前24位永远和倒数第8位一样。

  • 相关阅读:
    课程设计之第二次冲刺----第一天
    第一个spring冲刺总结
    课程设计之第一次冲刺----第九天
    课程设计之第一次冲刺----第八天
    课程设计之第一次冲刺----第七天
    课程设计之第一次冲刺----第六天
    课程设计之第一次冲刺---第5天
    课程设计之第一次冲刺---第四天
    课程设计之第一次冲刺---第3天
    课程设计之第一次冲刺---第二天
  • 原文地址:https://www.cnblogs.com/dongzhuangdian/p/5464803.html
Copyright © 2011-2022 走看看