我有6个 BigDecimals
,可以说
a,b,c,d,e,f and tot
所有这些值的总和(a,b,c,d,e,f
)等于tot
我正在计算平均值并存储在其他类型BigDecimal类型的变量中,只需说avgA, avgB, avgC, avgD, avgE, avgF and avgTot
即可。现在,如果我添加所有这些
avgA, avgB, avgC, avgD, avgE, avgF
此总和应等于avgTot
但所有平均值的总和(avgA, avgB, avgC, avgD, avgE, avgF
)不等于totAvg
这是示例代码
BigDecimal avgA = a.divide(new BigDecimal(counter), 15,RoundingMode.CEILING);
BigDecimal avgB = b.divide(new BigDecimal(counter), 15,RoundingMode.CEILING);
BigDecimal avgTot = tot.divide(new BigDecimal(counter), 15,RoundingMode.CEILING);
BigDecimal trimA = avgA.setScale(4, RoundingMode.CEILING);
BigDecimal trimB = avgB.setScale(4, RoundingMode.CEILING);
BigDecimal trimTot = avgTot.setScale(4, RoundingMode.CEILING);
样本值: -
trimA 0.0004
trimB 0.0000
trimC 0.0022
trimD 0.0047
trimE 0.0000
trimF 0.0002
trimTot 0.0076
问题是sum(TrimA..F)
不等于trimTot
。我必须确保sum(TrimA..F)
应等于trimTot
devious的事情是RoundingMode.CEILING
可确保加法上的最大错误,而不是RoundingMode.HALF_UP
:
天花板
0.00031 => 0.0004
0.00211 => 0.0022
------- ------ +
0.00242 0.0026
half_up(标准)
0.00033 => 0.0003
0.00216 => 0.0022
------- ------ +
0.00249 0.0025
地板
0.00043 => 0.0004
0.00216 => 0.0021
------- ------ +
0.00259 0.0025
so
BigDecimal trimA = avgA.setScale(4, RoundingMode.HALF_UP);
BigDecimal trimB = avgB.setScale(4, RoundingMode.HALF_UP);
BigDecimal trimTot = avgTot.setScale(4, RoundingMode.HALF_UP);
会最大程度地减少舍入错误,但不一定总是将其删除。
那么,您认为没有四舍五入到第四个小数。从15个职位到4时。
对于任何圆形方法来说,这根本不是这种情况,即一般圆(a b)= round(a) round(b)。
人们以高度精确地处理这些问题,以最大程度地减少可见的舍入错误的发生率,但这常常无法完全起作用。注意:Joop Eggen刚刚发布了这样的答案。请注意,我没有从判断力的意义上使用" Bodge"!
不提供为什么需要不可能的约束的解释,很难提供有用的建议。
一种明显的方法是定义 a,b,c为a/3 b/3 c/3的平均值。另一种方法是通过计算为理性数字来工作。这意味着要跟踪分子和分母或使用专门的Rational class
。