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