类型都是有表示范围的,整型也不例外
在32位系统上int占四个字节内存,能表示的整数范围是-231--231-1 (最高位是符号位)
unsigned int 也占四个字节内存,能表示的整数范围是0—232-1 (无符号位)
如果某个整型变量超过了其类型所能表示的范围,编译器该如何解释这个变量呢?
比如定义如下一个变量
char ch = 128 ;
由于char 是8bit 整型,所能表示的范围是 -128—127,超出了char所能表示的最大值
实际上,ch被解释成了-128
究其原因,这就要看变量的内存结构了,为了方便起见,假设某一个有符号整型长度为4bit,姑且称之为halfchar 吧,那么它能表示的范围是 -23—23-1, 即 -8 -- 7
数据不多,将它们的二进制形式依依列出
0000 – 0
0001 – 1
0010 – 2
0011 – 3
0100 – 4
0101 – 5
0110 – 6
0111 – 7
1000 – -8
1001 – -7
1010 – -6
1011 – -5
1100 – -4
1101 – -3
1110 – -2
1111 – -1
注:负数都是以补码表示的,并且有如下规则
一个负数的补码 = 对应正数的补码按位取反, 然后末位加1
所以 -7 的补码就是7 的补码0111 (正数的补码和原码相同) 按位取反1000, 然后末位加1
即1001,那么如果我定义Halfchar hch = 8 ;(超出最大值7)
先不管hch是什么类型,单看8的内存结构, 应该是01000,所以对应到上面的表,正好是-8 (高位的0已经被截断)
再比如Halfchar hch = -9 ; (超出最小值-8),-9的补码表示为 10111,对应到上面的表,正好是7(高位的1被截断)
由此我们得出一个小规律,一个数如果比它的类型最大值大1,那么它就变成了它的最小值,反之如果比它的最小值小1,那么就变成了它的最大值。以上讨论的是有符号数,这个规律同样适用于无符号数,比如
unsiged char ch = 256 ;实际上ch 被解释成了最小值0
Unsigned char ch = -1 (不合逻辑,为了验证而已) ch 实际上被解释成了 最大值255
也就是说,当一个类型的值超出其表示范围是,直接将其对应的内存结构截断成其类型能表示的范围即可。再比如
halfchar ch = 100 ; 100 的二进制表示为 0110 0100
而 halfchar 只占4bit,所以将高位的4bit截断,只保留低位4bit,即0100
所以ch = 100 实际上被解释成了 4
总的规律就是,当某一个类型的值超出范围时,首先考虑该值的内存结构,内存结构搞明白了,其它的就都好办了。
附:类型转换
1 低精度->高精度,内存结构不变
2 高精度->低精度,内存结构截断为低精度的范围
低精度->高精度
char ch = 65 ;
cout << (int)ch << endl ;
输出是65,如果直接输出,结果是A
高精度->低精度
int a = 22348016 ;
cout << (short)a << endl ;
结果是 240
分析:
22348016 的二进制表示为 00000000 10101010 00000000 11110000
而short 是16bit整型,去掉高16位剩下 00000000 11110000 即十进制 240