public class Test1 {
public static void main(String[] args) {
// Double aaa = 987842.6;
Double aaa = -2.3785548e+17;
String dist = String.valueOf(aaa);
BigDecimal KmBigDecimal = null;
try {
mileKmBigDecimal = new BigDecimal(dist);
System.out.println("mileKmBigDecimal:"+mileKmBigDecimal);
} catch (Exception e) {
}
BigDecimal multiplier = new BigDecimal("100");
BigDecimal resultBigDecimal = mileKmBigDecimal.multiply(multiplier);
System.out.println("resultBigDecimal:"+resultBigDecimal);
double v = resultBigDecimal.doubleValue();
System.out.println(v);
int distCm = resultBigDecimal.intValue();
System.out.println(distCm);
}
}
结果
mileKmBigDecimal:-2.3785548E+17
resultBigDecimal:-2.378554800E+19
-2.3785548E19
2147434496
原因
在 Java 中,当你调用 `BigDecimal.intValue()` 方法时,这个方法将尝试将 `BigDecimal` 的值转换为一个 `int` 类型的值。如果 `BigDecimal` 的值超出了 `int` 类型能表示的范围,即整数的最大值 `Integer.MAX_VALUE` (2147483647)或最小值 `Integer.MIN_VALUE`(-2147483648),该方法会返回一个截断的结果。这种截断的结果并非直接截断,而是通过取模 `Integer.MAX_VALUE + 1` 的方式来实现的。
在你的情形中,`resultBigDecimal` 的值是 `-2.3785548E+19`,远远超过了 `int` 类型的最小负值。因此,转换到 `int` 时,发生了数值的溢出和环绕,从而导致返回的结果为 2147434496。这是因为 Java 中的整型是 32 位的,且采用二进制补码形式存储,所以数值存储和算术运算时可导致溢出表现为循环或者反转。
具体点数值计算的过程是:
1. 原数值 `-2.3785548E+19` 相对于整型的范围绝对值太大。
2. 当它转换为整型时,实际上发生的是这个数值模上 `2^32`(因为整型是32位)的结果。
这里的关键是理解数值在某一点达到最大或最小值后,会回绕(wrap around)到反面的极端开始。在你的案例中,这种回绕导致了看似截然不同的值 2147434496 的出现。使用更大容量(如 `long` 或继续使用 `BigDecimal`)可以避免此类问题,如果对精度有具体要求的话。