BigDecimal/double 精度 - 数字向上取整
BigDecimal/double Precision - number rounds up higher
下面的第二个方法调用 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。为什么?我的 Java 版本在我的 Maven pom.xml
中设置如下
<java.version>1.8</java.version>
因为 double
无法保持那么高的精度;在初始化 BigDecimal
:
时,你不应该使用 double
,而应该使用 String
new BigDecimal("29.99993874900002");
new BigDecimal("-89.99999435599994");
参见:Is floating point math broken?
您正处于双精度浮点值的精度边缘,指定了 16 位数字,并且可用的小数精度只有 16 位数字。如果您完全跳过 BigDecimal,只需将双精度设置为 -89.99999435599994 并将其打印出来,您将得到 -89.99999435599995。
你的困惑与BigDecimal
无关。
double d = -89.99999435599994;
System.out.println(d); //or inspecting it in a debugger
产量:
-89.99999435599995
这正是 doubles
在 java 中的工作方式,结合 Double.toString
defines the String
-representation. This conversion happens before any method is invoked, when the literal is interpreted as double
. The details are specified in JLS Chapter 3.10.2. Floating-Point Literals and the JavaDocs of Double.valueOf(String)
.
的方式
如果您需要将值 -89.99999435599994
表示为 BigDecimal
,最简单的方法是使用 constructor taking a String,其他答案已经指出:
BigDecimal bd = new BigDecimal("-89.99999435599994");
BigDecimal bd = new BigDecimal("-89.99999435599994");
System.out.println(bd);
产量:
-89.99999435599994
下面的第二个方法调用 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。为什么?我的 Java 版本在我的 Maven pom.xml
中设置如下<java.version>1.8</java.version>
因为 double
无法保持那么高的精度;在初始化 BigDecimal
:
double
,而应该使用 String
new BigDecimal("29.99993874900002");
new BigDecimal("-89.99999435599994");
参见:Is floating point math broken?
您正处于双精度浮点值的精度边缘,指定了 16 位数字,并且可用的小数精度只有 16 位数字。如果您完全跳过 BigDecimal,只需将双精度设置为 -89.99999435599994 并将其打印出来,您将得到 -89.99999435599995。
你的困惑与BigDecimal
无关。
double d = -89.99999435599994;
System.out.println(d); //or inspecting it in a debugger
产量:
-89.99999435599995
这正是 doubles
在 java 中的工作方式,结合 Double.toString
defines the String
-representation. This conversion happens before any method is invoked, when the literal is interpreted as double
. The details are specified in JLS Chapter 3.10.2. Floating-Point Literals and the JavaDocs of Double.valueOf(String)
.
如果您需要将值 -89.99999435599994
表示为 BigDecimal
,最简单的方法是使用 constructor taking a String,其他答案已经指出:
BigDecimal bd = new BigDecimal("-89.99999435599994");
BigDecimal bd = new BigDecimal("-89.99999435599994");
System.out.println(bd);
产量:
-89.99999435599994