1. 自动转型
基本类型之间经常会需要进行数值类型转换,数值范围较小的数据类型可以自动转换为数值范围大的基本类型。
如图所示:
- 6个实心箭头:表示两个数值类型无信息丢失的转换。
- 3个虚线箭头:表示两个数值类型的转换可能会存在精度损失。
也就是说,147258369 是一个大整数,其包含的位数比 float 类型所能表达的位数多。
将这个整型数值转换为 float 是,会丢失精度。
int i = 147258369;
float f = i; // f = 1.47258368E8
因此,将两个不同数值类型进行算数操作时,会自动将两个类型转换为同一个类型,再进行计算。
自动转型:byte < short < char < int < long < float < double
- 当两个数值类型有一个是 double 类型,另一个数值也会转为 double 类型。
- 否则,有一个数值类型是 float 类型,另一个转换为 float 类型。
- 否则,有一个数值类型是 long 类型,另一个转换为 long 类型。
- 否则,两个数值都会被转换为 int 类型。
自动转型的值溢出问题
int x = 100000000;
int y = 10000;
long z = x * y; // z = -727379968
由于 x 与 y 都是 int 类型,相乘也是 int 类型,但值已经超过了 int 的表示范围,值溢出。
错误修改示例:
long z = (long) (x * y); // z = -727379968
此时,z 仍为负数,因为修改类型前,值已经移除。
正确修改示例:
long z = (long) x * y; // z = 1000000000000
此时,z 值为预期数据,原因:x 已转化为 long 类型,因此 y 也会自动转型为 long 类型,最后输出 long 类型的结果。
注意:通常对算术操作中的第一个操作数进行类型转换,避免第一次计算已经出现值溢出的情况。
2. 强制类型转换
除了在一些计算式,int 类型的数值将自动转换为 double 类型,又是也需要将 double 类型转换为 int 类型。
当然,此时会出现精度丢失,这种情况下,需要通过强制类型转换来实现该操作。
强制类型转换语法格式:目标类型 变量名 = (目标类型) 变量;
double x = 1.999;
int n = (int) x;// n = 1
强制类型转换通常是通过截断小数部分将浮点值转换为整型。
如果想得到更接近的整数,可以使用 Math 包的函数。
double x = 1.999;
int n = (int) Math.roud(x); // n = 2;