3.5 类型转换
(1) 精度问题
在上图中的实心箭头表示的类型转换不会存在信息丢失的问题;而3个虚箭头的转换表示可能有精度损失。
例如int转换为float时,由于int和float均为32位,且float有效位数有限,因此像123 456 789这样的大整数包含的位数比float类型所表达的位数多,因此转换时就会发生精度损失。
例:
int x=123456789;
float y=x;
System.out.println(y);
结果输出:1.23456792E8
当两个不同类型进行二元操作时(例如n+f,n为整型,f为浮点型),需要先将两个操作数转换为同一种类型再进行计算,转换原则为尽量不损失精度,详细转换规则:
如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型;
否则,如果其中一个操作数是float类型,另一个操作数就会转换为float类型;
否则,如果其中一个操作数是long类型,另一个操作数就会转换为long类型;
否则,两个操作数都将被转换为int类型;
注:根据以上规则,所有的byte、short和char型值在进行算术运算时都先被提升到int型;
例:
byte x=2;
byte y=3;
byte z=x+y;
编译时就会提示“可能损失精度”,所以应将z定义为int类型。
(2)强制类型转换
自动类型转换时会向无精度损失的方向进行,例如int转为double时可自动转换,但另一方面有时也需要将double转换成int。在Java中也允许进行这种数值之间的含精度损失的类型转换,在这种情况下,需要通过强制类型转换实现这个操作。
强制类型转换的语法格式为:
(目标类型)原始类型;
例如:
double x = 9.998;
int n = (int)x;
System.out.println(n); //这时变量n的值为9
注意:强制类型转换通过截断小数部分将浮点值转换为整型。
提示:如果想对浮点数进行舍入运算,以便得到最接近的整数(多数情况下采用这样的操作),那么就需要使用Math.round方法;
例如:
double x = 9.998;
int n = (int)Math.round(x);
//Math.round(double)返回的是long类型,因此仍需强制类型转换
System.out.println(n);
//这时变量n的值为10
java.lang.Object — java.lang.Math
|
警告:如果强制类型转换时,超出了目标类型的表示范围,结果就会截断成一个完全不同的值,例如(byte)300的实际值就会为44。
另外需要注意:不要在boolean类型与任何数值类型之间进行强制类型转换,如确实需要可采用条件表达式b?1:0。