前言
日常开发中会经常用到数值转化,将一个浮点数转化为整数,(int)num
和(int)(long)num
的结果会出现不同么?我们来写一个case:
public class Test {
public static void main(String[] args) {
float num1 = 100L;
System.out.println("case1-1: " + (int)num1);
System.out.println("case1-2: " + (int)(long)num1);
float num2 = 4123456789L;
System.out.println("case2-1: " + (int)num2);
System.out.println("case2-2: " + (int)(long)num2);
float num3 = 5123456789L;
System.out.println("case3-1: " + (int)num3);
System.out.println("case3-2: " + (int)(long)num3);
}
}
运行后的结果如下:
case1-1: 100
case1-2: 100
case2-1: 2147483647
case2-2: -171510528
case3-1: 2147483647
case3-2: 828489728
是不是很神奇呢,case2-1
和 case3-1
的结果竟然是相同的!!
分析
数值转化过程中会涉及到精度损失等,java语言规范中有相关的说明,参见 Narrowing Primitive Conversion,其中针对本文中涉及的两条如下:
- long类型转变为int类型时,直接将高4个字节去除,低4个字节作为int的值;
- float类型转为int/long时,如果不能表示,正数则用对应类型最大值,负数则用最小值;
int
的范围是 -2147483648 ~ 2147483647,long
的范围是 -9223372036854775808 ~ 9223372036854775807,测试case中的4123456789L和5123456789L都不能用int
表示,但可以用long
表示,所以在直接 float
转化为 int
时,输出了int的最大值 2147483647
。
在C和Cpp中,对于超过 int
范围的浮点,不论正负,结果均为-2147483648,即int
的最小值,和java有一些区别;
小结
对于精度可能损失的场景,合理的进行转化,减少不可预期结果的发生;
如有任何知识产权、版权问题或理论错误,还请指正。
转载请注明原作者及以上信息。