类型转换的原则:尽量保持值不变。
类型转换分为以下几类:
1.等长的整数类型之间的转换
(1)有符号整数------>无符号整数
有符号的补码不变,转换时将最高位的符号位理解成绝对值
例如:unsigned int a = -2;
-2(int)的原码:10000000 00000000 00000000 00000010
补码:11111111 11111111 11111111 11111110
a(unsigned int)的补码:11111111 11111111 11111111 11111110
原码:11111111 11111111 11111111 11111110
a = 65535 - 1 = 65534 = 2^32 - 2
(2)无符号整数------>有符号整数
补码不变, 最高位的理解改变(绝对值-->符号位)
例:int i = 127;
127(unsigned int)的补码: 00000000 00000000 00000000 01111111
127(int)的补码: 00000000 00000000 00000000 01111111
源码: 00000000 00000000 00000000 01111111 (i = 127)
2. 长整数 转 短整数
(1) 无符号的长整数 ---> 无符号的短整数截取补码的低位,最高位理解成绝对值
例:unsigned char uc = 128;
128(unsigned int)的补码: 0 00000000 00000000 00000000 10000000
128(unsigned char)的补码: 1 0000000
源码: 1 0000000 (uc = 128)
(2) 有符号的长整数 ---> 无符号的短整数
有符号的长整数-->有符号的短整数 --> 无符号的短整数
例:unsigned short us = -6;
-6(int)的源码:1 0000000 00000000 00000000 00000110
补码 : 1 1111111 11111111 11111111 11111010
-6(short)的补码: 11111111 11111010
-6(unsigned short)的补码: 11111111 11111010
源码: 11111111 11111010 (us = 65530)
(3) 无符号的长整数 ---> 有符号的短整数
无符号的长整数-->无符号的短整数-->有符号的短整数
例:char c = 130;130(unsigned int)的补码: 00000000 00000000 00000000 10000010
130(unsigned char)的补码: 10000010
130(char)的补码 : 1 0000010
反码 : 1 0000001
源码 : 1 1111110 (c = -126)
(4) 有符号的长整数 ---> 有符号的短整数
保留补码的低位,最高位理解成符号位
例:char c = 128;
128(int)的补码:00000000 00000000 00000000 10000000
128(char)的补码:1 10000000
反码:1 01111111
源码:1 10000000 (c = -128)
3. 短整数 转 长整数
(1) 有符号的短整数 转 有符号的长整数扩展补码: 多出来的高位被扩展成符号位
例:char c = -2;
int i = c;
-2(char)的源码:1 0000010
补码 : 1 1111110
-2(int)的补码 : 1 1111111 11111111 11111111 11111110
反码 :1 1111111 11111111 11111111 11111101
源码 :1 0000000 00000000 00000000 00000010 (i = -2)
(2) 无符号的短整数 转 无符号的长整数
扩展补码: 多出来的高位被扩展成0
例: unsigned char uc = 5;unsigned short us = uc;
5(unsigned char)的补码: 00000101
5(unsigned short)的补码: 00000000 00000101
源码: 00000000 00000101 (us = 5)
(3) 有符号的短整数 转 无符号的长整数
有符号的短整数 --> 有符号的长整数 --> 无符号的长整数
例: char c = -3;
unsigned short us = c;
-3(char)的源码:1 0000011
补码: 1 1111101
-3(short)的补码: 11111111 11111101
-3(unsigned short)的补码: 11111111 11111101
源码: 11111111 11111101 (us = 65533)
(4) 无符号的短整数 转 有符号的长整数
无符号的短整数-->无符号的长整数-->有符号的长整数
例: unsigned char uc = 254;
short s = uc;
254(unsigned char)的补码: 11111110
254(unsigned short)的补码: 00000000 11111110
254(short)的补码: 0 0000000 11111110
源码: 0 0000000 11111110 (s = 254)
4. 整数 转 浮点数
int i = 3;float f;
f = i; // f中的值是3.0
5. 浮点数 转 整数
截取整数部分int pi = 3.54; // pi=3
6. double 转 float
精度会下降,范围变小注意: double类型的数赋值给float类型的变量,
如果超出float的范围,变量的值是无穷大
总结:1.如果数据在目标类型所表示的范围之内,则值不变
2.如果数据为负数且不在目标类型所表示的范围之内,则用该范围的最大值加一再减去该数据的绝对值目标类型位数为n,该数据为i,则转换后的数为:(2^n - i)
3.如果数据为正数且不在目标类型所表示的范围之内,则用该范围的最大值加一再减去该数据得到差值,再用该范围的最 小值加上该差值
目标类型位数为n,该数据为i,则转换后的数为:(最小范围值 + (i - 2^n))
自动转换规则如下:
例:'a' + 2 结果: 99(int)
5 % 2 结果: 1(int)
注意: 1.float类型的数和非double类型的数运算的结果,最终都会转回为float
2.double类型的数赋值给float类型的变量,如果超出float的范围,变量的值是无穷大
补充知识:
1.整数
(1) 长度(64位系统)
类型 长度 范围
-----------------------------------------------------
char 1Byte -2^7 至 2^7 - 1
unsigned char 1B 0 至 2^8 - 1
short 2B -2^15 至 2^15 - 1
unsigned short 2B 0 至 2^16 - 1
int 4B -2^31 至 2^31 - 1
unsigned int 4B 0 至 2^32 - 1
long 8B(4B) -2^63 至 2^63 - 1
unsigned long 8B(4B) 0 至 2^64 - 1
2. 浮点数
(1) 编码结构+--------+---------+--------+
| 符号位 | 指数 | 尾数 |
+--------+---------+--------+
符号位: 1位, 0表示正数 1表示负数
指数 : 移码
尾数 : 补码
例: 324 = 3.24 x 10 ^ 2
101 = 1.01 x 2 ^ 2
0.101 x 2 ^ 3
+---------+---------+-------+
| 0 | 2 | 01 |
+---------+---------+-------+
(2) 长度(64位系统)
类型 长度 范围
--------------------------------------------------
float 4B -3.40E38 至 3.40E38
double 8B -1.79E308至 1.79E308
long double 16B(12B)