C++ 整型范围

1. 简述

    前两天被问道整数类型的范围,果断被鄙视了,回来好好看了下,这里做个总结。

2. 无符号整数

    在普通32位机器上,unsigned short int(2个字节), unsigned int(4个字节), unsigned long int(还是32个字节,因为以前的一些机器上int是2个字节的,short是1个字节的缘故,所以4个字节才被称为long)
    以unsinged int为例,4个字节,32个比特位,数据大小就是[0, 2^32-1],即32个位能够表示的数据范围的长度就是2^32。
    类似的对于char这个类型,其范围是[0, 2^8-1]

3. 有符号整数

    无符号的整数范围很简单就是[0, 2^N-1],其中N=数据的比特位。但是对于有符号数就不是这么简单了,因为有符号数的存储中,引入了原码,反码和补码的概念。
    引入这些概念主要就是为了负数运算的简化,即负数实际上以补码的形式存储的,在做负数与正数的加法时,就可以直接将两个数的比特位上的二进制相加了。为什么能够直接相加,这个不是讨论的重点,这里重点放在讨论补码的引入,对有符号数的存储范围有什么样的影响。
    首先,假设没有所谓的补码,无论整数还是负数都是原码表示,即除了符号位,其他的比特位都表示数据,这样和无符号数是相似的。
    比如:符号位=0时,表示正数,范围[0, 2^(N-1)-1]
            符号位=1时,表示负数,范围[-2^(N-1)-1, 0]
    这就引入了一个问题,两个0,即一个符号位为正数的0和符号数为负数的0,表示数据范围的长度就是2^N-1。实际上,引入了补码后,数据的范围的长度就是2^N,其中的“负0”是最小的整数。
    下面为了说明方便,我们假设数据长度为8位,对于32位的int,可以类推。
    对于正数,与无符号数是一样的,即 0000,0000     0000,0001     0111,1111分别表示0, 1, 127
    对于负数,根据补码来算,即1000,0000     1000,0001     1111,1111,负数的补码=负数的原码取反+1,因此我们要求其原码,就是先减一,再取反

                              先减一  0111,1111     1000,0000     1111,1110
                              再取反 1000, 0000     0111,1111     0000,0001 (这就是负数的绝对值)
                                        -128               -127             -1               即[-2^(N-1), -1]
     因此对于有符号整数,其范围是[-2^(N-1), 2^(N-1)-1]
     有一点很重要,就是,对于N位的数据,其范围长度就是2^N,不会存在正数0和负数0,而且负数的长度比正数多一个。

4. 参考资料

    int类型取值范围        http://blog.csdn.net/zabcd117/archive/2007/07/12/1687413.aspx
    计算机中的原码、反码和补码        http://www.cnitblog.com/mantou/archive/2005/08/01/1239.aspx
    补码-百度百科          http://baike.baidu.com/view/377340.htm

posted @ 2011-05-30 10:55  xiaodongrush  阅读(5158)  评论(2编辑  收藏  举报