BigDecimal一个用于进行更加精确的金额计算的封装类型
public BigDecimal(double val, MathContext mc) {
// 如果val是无限大的数或不是数字,抛出异常
if (Double.isInfinite(val) || Double.isNaN(val))
throw new NumberFormatException("Infinite or NaN")
// 根据双精度小数,转换为符号位,阶数和有效位根据JLS的公式 20.10.22
// 1. 根据IEEE754标准 将双精度浮点数 bit格式转换为long类型
// 如果这里输入double值为0.1,无法精确转换为二进制,得出的结果是错误的
long valBits = Double.doubleToLongBits(val);
// 2. 将valBits右移63位保留符号位,判断正负数 (0:正数,1:负数)
int sign = ((valBits >> 63) == 0 ? 1 : -1);
// 3. 获取阶码部分
int exponent = (int) ((valBits >> 52) & 0x7ffL);
// 4. 获取有效位
long significand = (exponent == 0
? (valBits & ((1L << 52) - 1)) << 1
: (valBits & ((1L << 52) - 1)) | (1L << 52));
略.......
.......
.......
}
在上面的代码中 double转换为二进制时,不是所有的小数都能够正确转换的,如0.1二进制为0.000110011001100…一个无限循环的二进制 这就会造成进度丢失