BigDecimal / double Precision-数字向上取整

时间:2018-07-16 22:57:43

标签: java precision bigdecimal

下面的第二个方法调用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>

3 个答案:

答案 0 :(得分:9)

因为double不能保持那么高的精度;初始化double时,您不应该使用String,而应该使用BigDecimal

new BigDecimal("29.99993874900002");
new BigDecimal("-89.99999435599994");

请参阅:Is floating point math broken?

答案 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 LiteralsJavaDocs 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。