java - BigDecimal Dividing with uneven decimals -


i trying work on program work multiple bigdecimal calculations necessary. @ quite confusing point because bigdecimal not cooperating how like. let me explain need do:

first takes monetary amount can have 2 decimal places. takes "allocations" how many accounts amount spread through.

the program should divide amount between accounts. of course in situations amount can not evenly divided, example $3.33 divided between 2 accounts. in case must either have 1 allocation cent or round number. rounding not option, every penny must accounted for. here have far:

totalallocations = transactionwizard.totalallocations;//set in class, how many accounts total spread      bigdecimal totalallocationsbd = new bigdecimal(totalallocations).setscale(2);//converts 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); 

later in class write values. have counter first set totalallocations. have loop write bit of information including dividedallocationamount. amounttotal had been 10 , had 2 allocations 5.00 written twice.

what want situations total can't evenly divided among allocations there 1 allocation hold remainder shown below:

if(remainderallocation.compareto(bigdecimal.zero) >0 && allocationcounter==1){                 adjamt.setvalue(remainderallocation);             }else{                 adjamt.setvalue(dividedallocationamount);             } 

the adjamt setting xml field, jaxb project.

the main issue have here numbers remainder. example if user selects 2 allocations , amount $3.33 program fail , give me rounding error.

exception in thread "awt-eventqueue-0" java.lang.arithmeticexception: rounding necessary     @ java.math.bigdecimal.commonneedincrement(unknown source)     @ java.math.bigdecimal.needincrement(unknown source)     @ java.math.bigdecimal.divideandround(unknown source)     @ java.math.bigdecimal.setscale(unknown source)     @ java.math.bigdecimal.setscale(unknown source)     @ model.creator.createtransaction(creator.java:341)     @ view.transactionwizard$2.actionperformed(transactionwizard.java:333)     @ javax.swing.abstractbutton.fireactionperformed(unknown source)     @ javax.swing.abstractbutton$handler.actionperformed(unknown source)     @ javax.swing.defaultbuttonmodel.fireactionperformed(unknown source)     @ javax.swing.defaultbuttonmodel.setpressed(unknown source)     @ javax.swing.plaf.basic.basicbuttonlistener.mousereleased(unknown source)     @ java.awt.component.processmouseevent(unknown source)     @ javax.swing.jcomponent.processmouseevent(unknown source)     @ java.awt.component.processevent(unknown source)     @ java.awt.container.processevent(unknown source)     @ java.awt.component.dispatcheventimpl(unknown source)     @ java.awt.container.dispatcheventimpl(unknown source)     @ java.awt.component.dispatchevent(unknown source)     @ java.awt.lightweightdispatcher.retargetmouseevent(unknown source)     @ java.awt.lightweightdispatcher.processmouseevent(unknown source)     @ java.awt.lightweightdispatcher.dispatchevent(unknown source)     @ java.awt.container.dispatcheventimpl(unknown source)     @ java.awt.window.dispatcheventimpl(unknown source)     @ java.awt.component.dispatchevent(unknown source)     @ java.awt.eventqueue.dispatcheventimpl(unknown source)     @ java.awt.eventqueue.access$500(unknown source)     @ java.awt.eventqueue$3.run(unknown source)     @ java.awt.eventqueue$3.run(unknown source)     @ java.security.accesscontroller.doprivileged(native method)     @ java.security.protectiondomain$javasecurityaccessimpl.dointersectionprivilege(unknown source)     @ java.security.protectiondomain$javasecurityaccessimpl.dointersectionprivilege(unknown source)     @ java.awt.eventqueue$4.run(unknown source)     @ java.awt.eventqueue$4.run(unknown source)     @ java.security.accesscontroller.doprivileged(native method)     @ java.security.protectiondomain$javasecurityaccessimpl.dointersectionprivilege(unknown source)     @ java.awt.eventqueue.dispatchevent(unknown source)     @ java.awt.eventdispatchthread.pumponeeventforfilters(unknown source)     @ java.awt.eventdispatchthread.pumpeventsforfilter(unknown source)     @ java.awt.eventdispatchthread.pumpeventsforfilter(unknown source)     @ java.awt.waitdispatchsupport$2.run(unknown source)     @ java.awt.waitdispatchsupport$4.run(unknown source)     @ java.awt.waitdispatchsupport$4.run(unknown source)     @ java.security.accesscontroller.doprivileged(native method)     @ java.awt.waitdispatchsupport.enter(unknown source)     @ java.awt.dialog.show(unknown source)     @ java.awt.component.show(unknown source)     @ java.awt.component.setvisible(unknown source)     @ java.awt.window.setvisible(unknown source)     @ java.awt.dialog.setvisible(unknown source)     @ view.mainview$15$1.run(mainview.java:398)     @ java.awt.event.invocationevent.dispatch(unknown source)     @ java.awt.eventqueue.dispatcheventimpl(unknown source)     @ java.awt.eventqueue.access$500(unknown source)     @ java.awt.eventqueue$3.run(unknown source)     @ java.awt.eventqueue$3.run(unknown source)     @ java.security.accesscontroller.doprivileged(native method)     @ java.security.protectiondomain$javasecurityaccessimpl.dointersectionprivilege(unknown source)     @ java.awt.eventqueue.dispatchevent(unknown source)     @ java.awt.eventdispatchthread.pumponeeventforfilters(unknown source)     @ java.awt.eventdispatchthread.pumpeventsforfilter(unknown source)     @ java.awt.eventdispatchthread.pumpeventsforhierarchy(unknown source)     @ java.awt.eventdispatchthread.pumpevents(unknown source)     @ java.awt.eventdispatchthread.pumpevents(unknown source)     @ java.awt.eventdispatchthread.run(unknown source) local instrument: web 

the same happens if total amount $10.51 , there 3 allocations. in reality want 2 allocations $5.25 , 3rd allocation $0.01. (since remainder). do?

of course in situations amount can not evenly divided, example $3.33 divided between 2 accounts. in case must either have 1 allocation cent or round number

[no optimization, best practices, error handling, data type conversion etc. plain working pseudo code.]

try this

        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; //-- each allocation          for(int i=1; i<allocations; i++){             system.out.println("allocation :" +i + " = "+rounded);         }          //-- adding adjusted rounding amount last 1         double adjustedamount = math.round((rounded+adjustment) * 100.0) / 100.0;          system.out.println("allocation :" +allocations +" = " + adjustedamount); 

output amount 3.33 2 allocations.

actual average 1.6649999618530273 rounded value: 1.66 allocation :1 = 1.66 allocation :2 = 1.67 //-- cent 

the same happens if total amount $10.51 , there 3 allocations. in reality want 2 allocations $5.25 , 3rd allocation $0.01. (since remainder). do?

now different above said above, can have 3.5, 3.5 & 3.51.

but if want 0.01 separately, alter above code allocations-1 & set remainder last allocation. 5.25 2 & remainder 0.01 3rd allocation, hope helps.


Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

c - Unrecognised emulation mode: elf_i386 on MinGW32 -