今天發(fā)現(xiàn), 當(dāng)我們有一個(gè)Double類型的變量, 想把它轉(zhuǎn)換成BigDecimal進(jìn)行計(jì)算時(shí),不能用new BigDecimal(double), 而是應(yīng)該用BigDecimal.valueOf(double), 前者返回的數(shù)值不精確。
例如:
new BigDecimal(10.0).multiply(new BigDecimal(0.15))
會(huì)得到1.49, 而
BigDecimal.valueOf(10.0).multiply(BigDecimal.valueOf(0.15))
會(huì)得到1.50。
額外說一點(diǎn),BigDecimal.valueOf(double)是這樣的邏輯:
return new BigDecimal(Double.toString(val));
先轉(zhuǎn)成String, 再new這個(gè)對(duì)象.
而MyBatis在轉(zhuǎn)換BigDecimal時(shí)用到的BigDecimalTypeHandler是這樣的:
@Override
public BigDecimal getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return rs.getBigDecimal(columnName);
}
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
if (!this.isBinaryEncoded) {
String stringVal = this.getString(columnIndex);
if (stringVal != null) {
BigDecimal val;
if (stringVal.length() == 0) {
val = new BigDecimal(this.convertToZeroLiteralStringWithEmptyCheck());
return val;
} else {
try {
val = new BigDecimal(stringVal);
return val;
} catch (NumberFormatException var5) {
throw SQLError.createSQLException(Messages.getString("ResultSet.Bad_format_for_BigDecimal", new Object[]{stringVal, columnIndex}), "S1009", this.getExceptionInterceptor());
}
}
} else {
return null;
}
} else {
return this.getNativeBigDecimal(columnIndex);
}
}
調(diào)用的是this.getString() 和this.convertToZeroLiteralStringWithEmptyCheck(), 先得到列的String值再new BigDecimal(), 所以MyBatis中可以放心使用BigDecimal不會(huì)出現(xiàn)誤差。