prabath
prabath

Reputation: 153

String to Integer Converting gives wrong output

In my program i'm posting the payment amount value to controller and i'm converting that value to Integer. Because I need to convert this value to cents before calling web service. I'm using java and convert String to Integer code given below

(int)(Double.parseDouble(httpRequest.getParameter(PAYMENT_AMOUNT).trim()) * 100);

payment.jsp

page look like this

Payment Amount: <input type="text" id="paymentAmount" name="paymentAmount" value="1.00" />

For many input values it gives the correct output.

But for some values like 8.03 as input it return 802 as output value . This happens in 9.03,9.04 ,10.03,10.04,11.03 etc ... what could be the reason for this issue?

Upvotes: 3

Views: 141

Answers (2)

jrm
jrm

Reputation: 331

As a side note, you might want to reconsider using int types to store cent values esp when dealing with large numbers.

To add more to earlier answers on floating-point issues in Java, and the need for BigDecimal, refer to some explanation here:

http://www.drdobbs.com/jvm/javas-floating-point-imprecision/240168744

You can change your code to:

(new BigDecimal(httpRequest.getParameter(PAYMENT_AMOUNT).trim(), MathContext.DECIMAL64)).multiply(new BigDecimal(100, MathContext.DECIMAL64)).intValue()

Another note: I would be cautious about assuming that you will get a String object back in the getParameter() call above esp. if someone is attempting to call your service without passing the PAYMENT_AMOUNT parameter.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533520

You need to round the result. The problem you have is that floating point numbers are almost but not exactly the number it appears when printed as a string. This shows up as a problem when you perform calculations.

I suggest you try

(int) Math.round( Double.parseDouble( httpRequest.getParameter(PAYMENT_AMOUNT).trim()) * 100);

In your specific case, you can see with BigDecimal what the actual representation of a double is

double d = 8.03;
BigDecimal bd = new BigDecimal(d);
System.out.println("bd: " + bd);
double d100 = d * 100;
System.out.println("d100: " + d100);
int i100 = (int) d100;
System.out.println("i100: " + i100);
int r100 = (int) Math.round(d100);
System.out.println("r100: " + r100);

prints

bd: 8.0299999999999993605115378159098327159881591796875
d100: 802.9999999999999
i100: 802
r100: 803

So you can see the actual value of 8.03 is slightly less than 8.03 which means however that when you * 100 and round down it means that you get 802 not 803 as expected.

The best solution is to round the result which finds the closest representable value.

Upvotes: 2

Related Questions