对我而言,似乎Double应遵循与MathContext.DECIMAL64中使用的IEEE标准相同的规则,但是,在这种情况下,我会得到不同的行为:
import java.math.BigDecimal;
import java.math.MathContext;
public class BigDecimalTest {
public static void main(String[] args) {
double foo = 8.7;
System.out.println(new BigDecimal(foo, MathContext.DECIMAL64));
System.out.println(new BigDecimal(Double.toString(foo)));
}
}
输出:
8.699999999999999
8.7
答案 0 :(得分:3)
BigDecimal任意精度带符号的十进制数。另一方面,double是浮点数,因此它意味着对所表示的数字有一些影响。
当您尝试从double创建Bigdecimal时,您将获得de double表示的值,在您的示例中为8.699999999999999。原因是双变量不能真正保持8.7。有关大小数的更多信息
当您将数字表示为字符串时,“字符串方法”返回值为“8.7”的值,并且结果表示该值为Bigdecimal。方法toString使用一些rools来表示一个double值作为String看看
当你使用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