Java 8任何好的舍入算法都可以舍入十进制并将总值返回为100

时间:2019-05-08 17:55:23

标签: java sorting

我目前正在寻找一种好的算法,该算法将进行舍入并返回总值为100。变量类型为BigDecimal。

我必须以2位数的格式返回BigDecimal,例如10.10

结果应该是这样的:

列表将具有

18.56、20.96、18.56、19.16和22.75。

18.56 + 20.96 + 18.56 + 19.16 + 22.75的总数应为100.00

使用这些值四舍五入时,应非常接近原始值。必须尽可能准确。

这不是唯一可能存在3个,4个,5个,6个,最多10个变量的场景。

任何帮助将不胜感激。

  1. 我对arraylist进行了四舍五入。
  2. 添加了所有值
  3. 检查了差异
  4. 现在,我打算反转舍入的排序数组,并从第一个和第二个值中减去该差,以使其等于100。

我不确定该算法的性能如何,但是如果您有更好的主意,我将不胜感激。

 @Test
    public void roundDecimalValuesAndCalculateTotalToHundredPercent() {
        BigDecimal no1 = BigDecimal.valueOf(18.562874251497007);
        BigDecimal no2 = BigDecimal.valueOf(20.958083832335326);
        BigDecimal no3 = BigDecimal.valueOf(18.562874251497007);
        BigDecimal no4 = BigDecimal.valueOf(19.161676646706585);
        BigDecimal no5 = BigDecimal.valueOf(22.75449101796407);
        List<BigDecimal> value = Arrays.asList(no1, no2, no3, no4, no5);


        scaleAndPrintList(value);
    }


    private void scaleAndPrintList(List<BigDecimal> list) {
        list.forEach(bigDecimal -> {
            System.out.println("Number is " + bigDecimal + ", ROUND_CEILING - " + bigDecimal.setScale(2, BigDecimal.ROUND_CEILING) + ", ROUND_HALF_UP - " + bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP));
        });

        list = list.stream()
                .map(bigDecimal -> bigDecimal.setScale(2, BigDecimal.ROUND_CEILING)).collect(Collectors.toList());

        final BigDecimal reduce = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);

        System.out.println("Addition " + reduce);

        // This is the error.
        final BigDecimal difference = BigDecimal.valueOf(100).subtract(reduce);

        System.out.println("Difference - " + difference);
    }

1 个答案:

答案 0 :(得分:1)

这取决于您要如何牺牲成员的精度。 为了在一遍操作中做到这一点,并将误差分布到各个成员中,我将收集(四舍五入)每个成员的一部分,并保持四舍五入,然后将四舍五入之前的前一个丢弃的差值添加到下一个变量中。最后一个成员的计算必须如下:100 - (summ of prev)-已经四舍五入到2位数字。

private static void scaleAndPrintList(List<BigDecimal> list) {
    BigDecimal sum = BigDecimal.valueOf(0);
    BigDecimal delta = BigDecimal.valueOf(0);
    for(int i=0;i<list.size()-1;i++) {
        BigDecimal bd = list.get(i);
        BigDecimal res = bd.add(delta).setScale(2,BigDecimal.ROUND_HALF_UP);
        System.out.println("Number " + bd + " => " + res + "   diff: " + bd.subtract(res));
        delta = bd.subtract(res);
        sum = sum.add(res);
    }
    // Last member
    BigDecimal bd = list.get(list.size()-1);
    BigDecimal res = BigDecimal .valueOf(100).subtract(sum);
    System.out.println("Last Number " + bd + " => " + res + "   diff: " + bd.subtract(res));
}

输出:

Number 18.564474251497007 => 18.56   diff: 0.004474251497007
Number 20.954483832335328 => 20.96   diff: -0.005516167664672
Number 18.562874251497007 => 18.56   diff: 0.002874251497007
Number 19.161676646706585 => 19.16   diff: 0.001676646706585
Last Number 22.75449101796407 => 22.76   diff: -0.00550898203593