我目前正在寻找一种好的算法,该算法将进行舍入并返回总值为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个变量的场景。
任何帮助将不胜感激。
我不确定该算法的性能如何,但是如果您有更好的主意,我将不胜感激。
@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);
}
答案 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