BigDecimal初始化后的Stange值

时间:2015-08-06 10:29:54

标签: java bigdecimal

我正试图以愚蠢的方式初始化HashMap:

HashMap<BigDecimal,BigDecimal> myMap = new HashMap<>();
myMap .put(new BigDecimal(1.7), new BigDecimal(1.5));
myMap .put(new BigDecimal(3.3), new BigDecimal(3));
myMap .put(new BigDecimal(5), new BigDecimal(4.5));
myMap .put(new BigDecimal(6.6), new BigDecimal(6));
myMap .put(new BigDecimal(11), new BigDecimal(10));
myMap .put(new BigDecimal(16.5), new BigDecimal(15));

但是插入上面的值是以下wang中的变化:

1.7 becomes 1.6999999999999999555910790149937383830547332763671875
3.3 becomes 3.29999999999999982236431605997495353221893310546875
6.6 becomes 6.5999999999999996447286321199499070644378662109375

为什么会发生这种情况?

4 个答案:

答案 0 :(得分:3)

使用BigDecimal.valueOf(double)静态方法:这将从您需要的双号的字符串表示初始化BigDecimal

答案 1 :(得分:2)

1.7等是浮点双字面。 1.7不能完全表示为double

它与1.7的最接近的近似值被传递给BigDecimal构造函数。并且BigDecimal能够表示不精确,从而给出观察到的效果。

1.5是一个二元理性,所以可以完全代表。

一种解决方法是使用BigDecimal构造函数,该构造函数将doubleMathContext对象一起使用:这允许您控制舍入行为。

另一种补救措施是使用BigDecimal.valueOf(1.7)。在内部,这将通过字符串利用转换。虽然容易处理,但计算量很大。

答案 2 :(得分:2)

请勿使用constructor which takes a double ,而使用String

根据双构造函数的doc:

  

这个构造函数的结果可能有些不可预测。有人可能会假设在Java中编写新的BigDecimal(0.1)会创建一个BigDecimal,它恰好等于0.1(未缩放值为1,标度为1),但它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能精确地表示为double(或者,就此而言,作为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于0.1,尽管有外观。

答案 3 :(得分:0)

您可以使用以下代码使用BigDecimal初始化HashMap。

    HashMap<BigDecimal, BigDecimal> myMap = new HashMap<>();
    myMap.put(BigDecimal.valueOf(1.7), BigDecimal.valueOf(1.5));
    myMap.put(BigDecimal.valueOf(3.3), BigDecimal.valueOf(3));
    myMap.put(BigDecimal.valueOf(3), BigDecimal.valueOf(4.5));
    myMap.put(BigDecimal.valueOf(6.6), BigDecimal.valueOf(6));
    myMap.put(BigDecimal.valueOf(11), BigDecimal.valueOf(10));
    myMap.put(BigDecimal.valueOf(16.5), BigDecimal.valueOf(15));
    Set set1 = myMap.entrySet();
    Iterator it1 = set1.iterator();
    while (it1.hasNext()) {
        Map.Entry meEntry = (Map.Entry) it1.next();
        System.out.println("key is: " + meEntry.getKey() + " & Value is: " + meEntry.getValue());

    }