rounding up/down is not consistant

Hi

I'm currently using the following code to round up/down a surcharge amount (and subsequent totalPaymentAmount) if a customer pays by Credit Card.

All works fine but I've just been alerted that when there is a rollover of 5 the surcharge, and new total + surcharge are no longer correct:

example:
customer pays 113.00
0.015 surcharge = 1.695 (which I guess should round up to 1.70 BUT IT DOESNT, IT ROUNDS DOWN TO 1.69)
totalPaymentAmount = 114.70 (WHICH IS 113.00 + 1.70, suddenly with a ROUNDED UP amount of 1.70?)

Any assistance with this would be great. Code needed please as I'm working on a live system and cant afford to try my medium level code.

I guess ideally it could work out the surcharge and add it to dOriginal to create totalPaymentAmount , then make surchargeAmt the difference of totalPaymentAmount - dOriginal ?

// work out surcharge amounts
double dOriginal    = Double.parseDouble(form.getPaymentAmount());
double dSurcharge   = dOriginal * 0.015;
String surchargeAmt = String.format("%.2f", dSurcharge);
String totalPaymentAmount  = String.format("%.2f", dOriginal + dSurcharge);

// set new amounts
form.setCardSurcharge(surchargeAmt);
form.setTotalPaymentAmount(totalPaymentAmount);

Open in new window

LVL 3
Neil ThompsonSenior Systems DeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CEHJCommented:
example:
customer pays 113.00
0.015 surcharge = 1.695
??

Oh i see, you mean a surcharge factor of 0.015, i.e. a one and a half percent surcharge.

You are in dangerous waters using double for financial purposes. Floating point values are approximate and you can get strange results without rounding entering at all.

I would use either BigDecimal or use integral values and convert to pennies only when necessary.

Contrast the two:

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;


public class Money {
    public static void main(String[] args) {
        final double SURCHARGE = 0.015;
        double d = Double.parseDouble("113.0") * SURCHARGE;
        System.out.printf("%f%n", d);

        BigDecimal BD_SURCHARGE = new BigDecimal("0.015");
        BigDecimal bd = new BigDecimal("113.0");
        MathContext mc = new MathContext(2, RoundingMode.HALF_UP);
        BigDecimal result = bd.multiply(BD_SURCHARGE, mc);
        System.out.printf("%s%n", result);
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Neil ThompsonSenior Systems DeveloperAuthor Commented:
thanks

How would I go about dropping just the required buts into my code above, is this right? (apologes, JAVA level low-medium)

Also how do I get the value of the surcharge amount (e.g. 1.70 for a payment of 113.00) as I need to set that form.setCardSurcharge(surchargeAmt)

Is it right the way I am casting? to a string?

Neil

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

BigDecimal BD_SURCHARGE = new BigDecimal("0.015");
BigDecimal bd = new BigDecimal(form.getPaymentAmount());
MathContext mc = new MathContext(2, RoundingMode.HALF_UP);
BigDecimal result = bd.multiply(BD_SURCHARGE, mc);
System.out.printf("%s%n", result);
            
String surchargeAmt = ???????????.toString();
String totalPaymentAmount  = result.toString();

// set new amounts
form.setCardSurcharge(surchargeAmt);
form.setTotalPaymentAmount(totalPaymentAmount);
0
CEHJCommented:
Also how do I get the value of the surcharge amount (e.g. 1.70 for a payment of 113.00)
But that is the value of 'result' ...

Perhaps this is what you really mean?

        String totalPaymentAmount = bd.add(result).toString();
        System.out.println(totalPaymentAmount);

Open in new window

0
Neil ThompsonSenior Systems DeveloperAuthor Commented:
Excellent that's it, thanks
0
CEHJCommented:
:)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.