下面的第二个方法调用setYCoordinate()会得到错误的值-89.99999435599995,而不是-89.99999435599994。
第一次调用setXCoordinate()会获得正确的值29.99993874900002。
setXCoordinate(BigDecimal.valueOf(29.99993874900002))
setYCoordinate(BigDecimal.valueOf(-89.99999435599994))
我在BigDecimal.valueOf()中放置了一个断点-该方法的代码如下-
public static BigDecimal valueOf(double val) {
// Reminder: a zero double returns '0.0', so we cannot fastpath
// to use the constant ZERO. This might be important enough to
// justify a factory approach, a cache, or a few private
// constants, later.
return new BigDecimal(Double.toString(val));
}
在检查时,valueOf即“ double val”本身收到的参数为-89.99999435599995。为什么?我在Maven pom.xml中设置了如下的Java版本
<java.version>1.8</java.version>
答案 0 :(得分:9)
因为double
不能保持那么高的精度;初始化double
时,您不应该使用String
,而应该使用BigDecimal
:
new BigDecimal("29.99993874900002");
new BigDecimal("-89.99999435599994");
答案 1 :(得分:1)
您的困惑与BigDecimal
无关。
double d = -89.99999435599994;
System.out.println(d); //or inspecting it in a debugger
产量:
-89.99999435599995
这只是doubles
在Java中的工作方式,与Double.toString
定义String
表示形式的方式结合在一起。当文字被解释为double
时,此转换发生在调用任何方法之前。详细信息在JLS Chapter 3.10.2. Floating-Point Literals和JavaDocs of Double.valueOf(String)
中指定。
如果您需要将值-89.99999435599994
表示为BigDecimal
,则最简单的方法是使用constructor taking a String,因为其他答案已经指出:
BigDecimal bd =新的BigDecimal(“-89.99999435599994”);
BigDecimal bd = new BigDecimal("-89.99999435599994");
System.out.println(bd);
产量:
-89.99999435599994
答案 2 :(得分:0)
对于双精度浮点值,您就在精度的边缘,指定了16位数字,而十进制精度只有整整16位数字。如果您完全跳过BigDecimal,只需将双精度设置为-89.99999435599599994并打印回去,就会得到-89.99999435599995。