A BigDecimal 任意精度有符号十进制数。另一方面,双精度数是一个浮点数,因此它意味着对所表示的数字有一些印象。
当您尝试从 double 创建 Bigdecimal 时,您会得到 de double 表示的值,在您的示例中为 8.699999999999999。原因是双变量并不能真正准确地保持 8.7。有关大小数的更多信息
http://goo.gl/tRMLhA
当您将数字表示为字符串时,“8.7”值由 to 字符串方法返回,并且连续地就是分配给 Bigdecimal 的值。方法 toString 使用一些 rools 将 double 值表示为 String 看看
http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#toString(double)&bwsCriterion=toString&bwsMatch=3
当您使用 MathContext.DECIMAL64 时,您是在说“好的,我知道双数存在一些缺陷,所以我希望您使用 16 位的精度和舍入模式一半进行舍入”这正是你得到的。Java采用8.7的双重表示,即8.6999999999999993并将其四舍五入为16位,结果为8.699999999999999,因为数字17是“3”,因此四舍五入的结果是保留数字16,因为它是9 .
有关 MathContext.DECIMAL64 含义的信息:http:
//goo.gl/fVUehh
如果您想获得 8.7,只需使用低于 16 位的精度即可。
示例代码
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
double foo = 8.7;
System.out.println(new BigDecimal(foo, MathContext.DECIMAL64));
System.out.println(new BigDecimal(foo, new MathContext(16)));
System.out.println(new BigDecimal(foo, new MathContext(17)));
System.out.println(new BigDecimal(foo, new MathContext(1)));
System.out.println(new BigDecimal(foo, new MathContext(2)));
System.out.println(new BigDecimal(foo, new MathContext(3)));
System.out.println(new BigDecimal(foo, new MathContext(15)));
System.out.println(new BigDecimal(Double.toString(foo)));
}
输出
8.699999999999999
8.699999999999999
8.6999999999999993
9
8.7
8.70
8.70000000000000
8.7
有关 BigDecimal 和双打的更多信息
https://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal