Java 创建5美分的差异+;-在大十进制比较中
我们根据必须与原始总数相匹配的百分比计算总数。然而,如果不使用浮点数,总数永远不会匹配 例如 总百分比根据327.81计算得出 非四舍五入金额示例Java 创建5美分的差异+;-在大十进制比较中,java,Java,我们根据必须与原始总数相匹配的百分比计算总数。然而,如果不使用浮点数,总数永远不会匹配 例如 总百分比根据327.81计算得出 非四舍五入金额示例 30% 98.343 20% 65.562 30% 98.343 20% 65.562 Total 327.81 30% 98.34 20% 65.56 30% 98.34 20% 65.56 Total 327.80 四舍五入金额示例 30% 98.343 20% 65.562 30%
30% 98.343
20% 65.562
30% 98.343
20% 65.562
Total 327.81
30% 98.34
20% 65.56
30% 98.34
20% 65.56
Total 327.80
四舍五入金额示例
30% 98.343
20% 65.562
30% 98.343
20% 65.562
Total 327.81
30% 98.34
20% 65.56
30% 98.34
20% 65.56
Total 327.80
我的金额需要四舍五入到一种货币格式,但是您会注意到四舍五入的金额是327.80,比我们原来的327.81少1美分
最后,我需要验证这两个数量是否相等-这显然不会验证。管理层告诉我在逻辑上增加一个0.05的偏差。我能够比较彼此相等的值,但是我不确定如何将方差添加到等式中。有人能帮我想一想如何把它加入到我的病情中去吗
这是我当前的代码,比较它们是否相等
if ( this.pr.getRequisitionTotal() != null
&& this.pr.getRequisitionTotal().compareTo(lineItemTotal) != 0
&& this.reviewedAuditActions())
{
this.form.recordError("Requisition total must equal line item running total.");
}
标准解决方案是跟踪“真实”金额和四舍五入版本之间的累积偏差,并调整四舍五入以保持偏差小于0.5。这里是使用BigDecimal实现这个概念的一个例子,这使得它有点冗长,但避免了使用浮点时常见的表示问题 例如,如果创建了一个名为
RoundingAccumulator
的类来封装此行为,则可以对代码的其余部分隐藏混乱的细节
BigDecimal value = new BigDecimal("327.81");
BigDecimal[] percents = new BigDecimal[] {
new BigDecimal(30),
new BigDecimal(20),
new BigDecimal(30),
new BigDecimal(20) };
BigDecimal accError = BigDecimal.ZERO;
BigDecimal maxError = new BigDecimal("0.005");
BigDecimal adjust = new BigDecimal("0.01");
BigDecimal hundred = new BigDecimal("100");
BigDecimal total = BigDecimal.ZERO;
for (BigDecimal pct : percents)
{
BigDecimal unrounded = value.multiply(pct).divide(hundred);
BigDecimal rounded = unrounded.setScale(2,RoundingMode.HALF_EVEN);
BigDecimal error = rounded.subtract(unrounded);
BigDecimal correction = BigDecimal.ZERO;
accError = accError.add(error);
if (accError.abs().compareTo(maxError) > 0)
correction = accError.signum() > 0 ? adjust.negate() : adjust;
rounded = rounded.add(correction);
accError = accError.add(correction);
System.out.println(unrounded.toString() + " " + rounded.toString() + " " + error.toString() + " " + accError.toString() + " " + correction.toString());
total = total.add(rounded);
}
System.out.println("Total is " + total.toString());
}
最终双ε=0.05;
双a=0.5;
双b=0.51;
如果(Math.abs(a-b)使用。取整后的金额通常不等于原始总额-这是取整后不可避免的结果。如果您的金额必须合计(为什么一定要合计?),则您可能需要将总额拆分为小的离散金额(例如,美分或美分的十分之一),并按照百分比进行分配(这通常会导致很小的差异)。将差异添加或减去到最大值。:)大家好,我使用的是bigdecimal,很抱歉我显示了我的数据类型。谢谢,这比我计划的要好得多。