【发布时间】:2016-01-07 16:04:59
【问题描述】:
我正在尝试开发一个程序来处理必要的多个 BigDecimal 计算。我处于相当混乱的状态,因为 BigDecimal 没有按照我的意愿进行合作。让我解释一下我需要它做什么:
首先它需要一个货币金额,最多可以有两位小数。然后它需要“分配”,这基本上是该金额将通过多少个帐户进行分配。
程序现在应该在账户之间分配金额。当然,在某些情况下,金额不能平均分配,例如 3.33 美元在 2 个帐户之间分配。在这种情况下,您必须有 1 个分配额外的美分或四舍五入。四舍五入不是一种选择,每一分钱都必须考虑在内。这是我到目前为止所拥有的:
totalAllocations = TransactionWizard.totalAllocations;//Set in another class, how many accounts total will be spread
BigDecimal totalAllocationsBD = new BigDecimal(totalAllocations).setScale(2);//Converts to big decimal.
amountTotal = (BigDecimal) transInfo.get("amount"); // set total amount
MathContext mc = new MathContext(2);
remainderAllocation = amountTotal.remainder(totalAllocationsBD, mc);
dividedAllocationAmount = amountTotal.divide(totalAllocationsBD, MathContext.DECIMAL32);
dividedAllocationAmount=dividedAllocationAmount.setScale(2);
在课后,我实际上写了这些值。我首先有一个计数器,它设置为 totalAllocations。然后我有一个循环,它将写入一些信息,包括divideAllocationAmount。所以说总金额为 10,我有两次分配,那么 5.00 将被写入两次。
我想要的是对于总数不能在分配之间平均分配的情况,以便有一个额外的分配来保存剩余部分,如下所示:
if(remainderAllocation.compareTo(BigDecimal.ZERO) >0 && allocationCounter==1){
adjAmt.setValue(remainderAllocation);
}else{
adjAmt.setValue(dividedAllocationAmount);
}
adjAmt 只是设置一个 XML 字段,这是一个 JAXB 项目。
我在这里遇到的主要问题是带有余数的数字。例如,如果用户选择 2 个分配并且金额为 3.33 美元,那么程序将失败并给我一个舍入错误。
Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: Rounding necessary
at java.math.BigDecimal.commonNeedIncrement(Unknown Source)
at java.math.BigDecimal.needIncrement(Unknown Source)
at java.math.BigDecimal.divideAndRound(Unknown Source)
at java.math.BigDecimal.setScale(Unknown Source)
at java.math.BigDecimal.setScale(Unknown Source)
at model.Creator.createTransaction(Creator.java:341)
at view.TransactionWizard$2.actionPerformed(TransactionWizard.java:333)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.WaitDispatchSupport$2.run(Unknown Source)
at java.awt.WaitDispatchSupport$4.run(Unknown Source)
at java.awt.WaitDispatchSupport$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.WaitDispatchSupport.enter(Unknown Source)
at java.awt.Dialog.show(Unknown Source)
at java.awt.Component.show(Unknown Source)
at java.awt.Component.setVisible(Unknown Source)
at java.awt.Window.setVisible(Unknown Source)
at java.awt.Dialog.setVisible(Unknown Source)
at view.MainView$15$1.run(MainView.java:398)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Local Instrument: WEB
如果总金额为 10.51 美元并且有 3 个分配,也会发生同样的情况。实际上,我想要的是两次分配为 5.25 美元,第三次分配为 0.01 美元。 (因为那是余数)。我该怎么办?
【问题讨论】:
-
我该怎么做清楚地写下您的需求/案例并将其拆分为步骤将有助于包括您在内的所有人很好地理解它并开始编码。没有通读全文,发现有点混乱。
-
@NayanWadekar 你应该学会从写得不好的文本中提取重要信息 :) 这里的 2 个建议是: a) 阅读有关如何在 Java 中进行会计处理的约定。如果您没有小数便士,BigDecimal 不是的方法。 b) 阅读how to debug small programs,错误就在堆栈跟踪中(它还会将您指向 Javadoc 中的相关位置)
-
@Ordous 具有讽刺意味的是,即使在阅读了“写得不好的文字”并建议我之后,你也没有回答。我可以,但我不想,干杯。
-
感谢您的建议,但我看不出问题是如何不清楚的?我想知道一个 BigDecimal 可以被另一个 BigDecimal 整除多少次,然后将余数放入它自己的变量中?究竟有什么不清楚的地方?
-
你想用 RoundingMode.FLOOR 分割。
标签: java bigdecimal