美文网首页
数据类型的取值范围和溢出

数据类型的取值范围和溢出

作者: abb266389fd0 | 来源:发表于2016-07-26 13:49 被阅读371次

    不知何为原码反码补码的童鞋请猛戳这里,这篇文章要说的是,数据类型的取值范围和溢出

    • 取值范围

    数据类型的取值范围有一个公式:-2(n-1)~2(n-1)-1
    n为整型的内存占用位数,所以int类型32位那么就是-(231)~231 -1即-2147483648~2147483647
    但是,为什么最小负数绝对值总比最大正数多1???

    以char为例:
    -0:原码是1000 0000,补码为1 0000 0000,由于char是八位,所以取低八位0000 0000。+0:原码为0000 00000,补码为也为0000 0000,虽然补码0都是相同的,但是有两个0,既然有两个0,况且0既不是正数,也不是负数,用原码0000 0000表示就行了,这样一来,有符号的char,原码都用来表示-127~127之间的数了,唯独剩下原码1000 0000没有用

    现在再来探讨一下关于剩下的那个1000 0000

    -128的原码是1 1000 0000,9位,最高位符号位,再算它的反码1 0111 1111,进而,补码为1 1000 0000,这是-128的补码,发现和原码一样,但是在char型中,是可以用1000 000表示-128的。关键在于char是8位,它把-128的最高位符号位1丢弃了,截断后-128的原码为1000 0000和-0的原码相同,也就是说1000 0000和-128丢弃最高位后余下的8位相同,所以才可以用-0表示-128。这样,当初剩余的-0(1000 0000),被拿来表示截断后的-128,因为即使截断后的-128和char型范围的其他数(-127~127)运算也不会影响结果,所以才敢这么表示-128

    • 数据溢出

    既然说-128和char型范围的其他数(-127~127)运算也不会影响结果,那么我们就来运算一下,运算完之后也就知道了数据溢出是怎么回事了:(注意计算机内部以补码形式进行运算的,所以运算结果为补码,补码转原码的过程为:先减一,然后符号位不变其他位取反)

    -   128 + 127:
        1000 0000
    +   0111 1111
    =   1111 1111,符号位为1表示负数,减一得到反码1111 1110,取反得到源码1000 0001,即-1
    
          127+(-127):
          0111 1111
    +     1000 0001
    =   1 0000 0000,高位溢出,取后八位,得0
    
          -128+(-1):
          1000 0000
    +     1111 1111
    =   1 0111 1111,高位溢出,取后八位,符号位为0表示正数,所以得127
    
        127+1:
        0111 1111
    +   0000 0001
    =   1000 0000,前面我们已经讨论过,1000 0000表示-128
    

    搞清了数据类型的取值范围和溢出,并且知道计算机内部是以补码形式进行运算的,那么也就不难理解为什么下面这个程序会输出-1了

    #include<stdio.h>
    int main()
    {
        //1111 1111
        //1111 1110
        //1000 0001
        char c = 0xff;
        printf("%d\n",c);
    }
    

    相关文章

      网友评论

          本文标题:数据类型的取值范围和溢出

          本文链接:https://www.haomeiwen.com/subject/hgunjttx.html