我正在尝试使用需要进行多个BigDecimal计算的程序。我很困惑,因为BigDecimal无法配合我的意愿。让我解释一下我需要做什么:

首先,它需要一个金额,最多可以有两个小数位。然后采用“分配”,这基本上就是该数量将分配给多少个帐户。

该程序现在应该在两个帐户之间分配金额。当然,在某些情况下,金额无法平均分配,例如$ 3.33在两个帐户之间分配。在这种情况下,您必须为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的计数器。然后,我有一个循环,该循环将写入一些信息,包括dividedAllocationAmount。因此,说amountTotal为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。 (因为那是剩余的)。我该怎么办?

最佳答案

当然,在某些情况下,金额不能平均分配,
  例如$ 3.33分配给两个帐户。在这种情况下,您必须
  分配1或多一分或四舍五入


[没有优化,最佳实践,错误处理,数据类型转换等。普通的伪代码。]

尝试这个

        float amount = 3.33f;

        int allocations = 2;

        double average = amount/allocations;

        System.out.println("ACTUAL AVERAGE "+average);

        double rounded = Math.round(average * 100.0) / 100.0;

        System.out.println("ROUNDED VALUE: "+rounded);

        double adjustment = average - rounded;

        adjustment*=allocations; //-- FOR EACH ALLOCATION

        for(int i=1; i<allocations; i++){
            System.out.println("Allocation :" +i + " = "+rounded);
        }

        //-- ADDING ADJUSTED ROUNDING AMOUNT TO LAST ONE
        double adjustedAmount = Math.round((rounded+adjustment) * 100.0) / 100.0;

        System.out.println("Allocation :" +allocations +" = " + adjustedAmount);


输出2.33的金额3.33。

ACTUAL AVERAGE 1.6649999618530273
ROUNDED VALUE: 1.66
Allocation :1 = 1.66
Allocation :2 = 1.67 //-- EXTRA CENT



  如果总金额为$ 10.51并且有3个,则会发生相同的情况
  分配。实际上,我想要的是两个分配
  $ 5.25,第3笔分配为$ 0.01。 (因为那是
  余)。我该怎么办?


现在这与您上面所说的不同,您可以拥有3.5、3.5和3.51。

但是,如果您希望单独分配0.01,则更改上面的代码分配-1并将其余的设置为最后一个分配。因此,第二分配为2,是5.25,第三分配为,其余是0.01,希望这会有所帮助。

关于java - BigDecimal除法,小数点不均匀,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34659763/

10-11 03:27
查看更多