[英]BigDecimal/double Precision - number rounds up higher
The second of below method calls, to setYCoordinate(), gets incorrect value -89.99999435599995 instead of -89.99999435599994. 以下方法调用中的第二个调用setYCoordinate(),得到的值不正确-89.99999435599995而不是-89.99999435599994。
The first call to setXCoordinate() gets correct value 29.99993874900002. 第一次调用setXCoordinate()得到正确的值29.99993874900002。
setXCoordinate(BigDecimal.valueOf(29.99993874900002))
setYCoordinate(BigDecimal.valueOf(-89.99999435599994))
I put a breakpoint inside BigDecimal.valueOf() - this method's code looks as below - 我在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));
}
The argument received by valueOf ie "double val" itself is -89.99999435599995 when inspected. valueOf收到的参数即“双val”本身在检查时为-89.99999435599995。 Why?
为什么? I have Java version set as below in my Maven pom.xml
我在Maven pom.xml中设置了Java版本,如下所示
<java.version>1.8</java.version>
Because a double
can't retain that much precision; 因为
double
不能保持那么高的精度; you shouldn't use a double
, but rather a String
when initializing your BigDecimal
: 在初始化
BigDecimal
时,不应该使用double
,而是使用String
:
new BigDecimal("29.99993874900002");
new BigDecimal("-89.99999435599994");
See: Is floating point math broken? 请参阅: 浮点数学是否已损坏?
Your confusion has nothing to do with BigDecimal
. 你的困惑与
BigDecimal
无关。
double d = -89.99999435599994;
System.out.println(d); //or inspecting it in a debugger
yields: 收益率:
-89.99999435599995
-89.99999435599995
This is just the way doubles
work in java, in combination with the way Double.toString
defines the String
-representation. 这就是在
doubles
的方式,结合Double.toString
定义String
Double.toString
的方式。 This conversion happens before any method is invoked, when the literal is interpreted as double
. 在将文字解释为
double
时,在调用任何方法之前进行此转换。 The details are specified in JLS Chapter 3.10.2. 详细信息在JLS第3.10.2章中指定。 Floating-Point Literals and the JavaDocs of
Double.valueOf(String)
. 浮点字面值和
Double.valueOf(String)
的JavaDoc 。
If you need to express the value -89.99999435599994
as BigDecimal
, the easiest way is to use the constructor taking a String , as other answers have already pointed out: 如果你需要将值
-89.99999435599994
表示为BigDecimal
,最简单的方法是使用构造函数获取String ,因为其他答案已经指出:
BigDecimal bd = new BigDecimal("-89.99999435599994"); BigDecimal bd = new BigDecimal(“ - 89.99999435599994”);
BigDecimal bd = new BigDecimal("-89.99999435599994");
System.out.println(bd);
yields: 收益率:
-89.99999435599994
-89.99999435599994
You're right on the edge of precision for a double-precision floating point value, with 16 digits specified, and there's just shy of a full 16 digits of decimal accuracy available. 对于双精度浮点值而言,您处于精度的边缘,指定了16位数,并且只有十几位小数精度可用。 If you skip BigDecimal entirely, just set a double to -89.99999435599994 and print it back out, you'll get -89.99999435599995.
如果您完全跳过BigDecimal,只需将一个双精度设置为-89.99999435599994并将其打印出来,您将得到-89.99999435599995。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.