使用Double进行规范化

时间:2016-06-10 18:45:17

标签: java double rounding

我有一组具有不同小数位数的双打。我需要获取这些值的SUM(),然后将它们全部归一化,使它们SUM()为1.此外,我要求在最终结果中将小数位数限制为4.要完成此操作我尝试过以下操作:

normalizationFactor = 1/sumOfAllDoublesInGroup;

for(Object myObject : myGroupOfObjects){
     myObject.setDoubleValue = round(myObject.getDoubleValue * normalizationFactor),4);
}

private Double round (Double doubleValue, Integer decimalPlaces) {
    if (places < 0) throw new IllegalArgumentException();

    BigDecimal bd = new BigDecimal(value);
    bd = bd.setScale(places, RoundingMode.HALF_UP);
    return bd.doubleValue();
}

这里的缺点是在舍入后我仍然不能保证所有双打的SUM()仍然是== 1.我将不胜感激。

要明确唯一的要求是

1)我得到一组数字,每个数字都有不同的小数位数。 2)完成所有操作后,每个数字限制为4位小数。 3)组中所有数字的最终SUM()必须完全= 1

1 个答案:

答案 0 :(得分:0)

您的代码在double和BigDecimal之间有很多转换。这些转换可能会为您的值添加双精度误差。请找到下面的代码,所有数字都存储在BigDecimal中。

    List<BigDecimal> myGroupOfObjects = new ArrayList<>();
    myGroupOfObjects.add(new BigDecimal("0.3"));
    myGroupOfObjects.add(new BigDecimal("0.1"));
    myGroupOfObjects.add(new BigDecimal("0.2"));
    myGroupOfObjects.add(new BigDecimal("0.2"));

    BigDecimal sumOfAllDoublesInGroup = new BigDecimal("0.8"); // #HardCoding

    BigDecimal normalizationFactor = new BigDecimal("1.0")
        .divide(sumOfAllDoublesInGroup);

    BigDecimal result = new BigDecimal(0);
    for(BigDecimal myObject : myGroupOfObjects){
        myObject = myObject.multiply(normalizationFactor)
                .setScale(4, RoundingMode.HALF_UP);

        result = result.add(myObject);
    }

Result: 
0.3750
0.1250
0.2500
0.2500
------
1.0