如何实现float到int的精确转换,转换不精确时抛出异常
比较返回true的原因
Java中不同基本类型做==比较时,会先向取值范围更大的类型自动拓宽后再比较。你案例中的int值2147483647(即Integer.MAX_VALUE)在拓宽为float类型时,由于float只有23位有效尾数,无法精确表示2^31附近的连续整数,2147483647会被向上舍入为2147483648.0,和你的原始float值完全相等,因此比较结果返回true。
同时Math.round(float)本身的实现逻辑就决定了,当输入值超过int的取值范围时,会直接返回Integer.MAX_VALUE或Integer.MIN_VALUE,这也是你拿到错误int值的直接原因。
可靠的精确转换方案
下面的方案性能远高于转字符串比较,可覆盖所有边界场景:
- 第一步:将float转为double后调用
Math.round拿到四舍五入后的long值,避免int溢出截断 - 第二步:判断long值是否在int的取值范围内,超出则直接抛出异常
- 第三步:将得到的int值转回float,和原始float值做相等比较,不一致则说明转换存在精度损失,抛出异常
示例代码如下:
public static int safeFloatToInt(float f) throws ArithmeticException { // 转double后round得到long,避免int溢出 long roundedLong = Math.round((double) f); // 校验是否在int取值范围内 if (roundedLong < Integer.MIN_VALUE || roundedLong > Integer.MAX_VALUE) { throw new ArithmeticException("Float值 " + f + " 超出int取值范围"); } int intVal = (int) roundedLong; // 校验转换精度 if ((float) intVal != f) { throw new ArithmeticException("Float值 " + f + " 无法精确转换为int"); } return intVal; }
你给出的测试用例中,输入float值为2147483648.0,round后的long值为2147483648,超出int最大值,会直接抛出异常,不会出现之前的错误比较结果。
内容的提问来源于stack exchange,提问作者vbezhenar
相关产品推荐
相关产品推荐

