Showing posts with label java BigDecimal conversion. Show all posts
Showing posts with label java BigDecimal conversion. Show all posts

Saturday, February 11, 2012

To deal with Java BigDecimal object within a financial application

Hi Guyz,

I am working for one of the UK government owned bank from last two years. I worked for International payments project. Personally, I have learned many things as a developer. Thought of share my technical learning’s in my personal blog to benefit others as well.

From the post title, you can come to know that I am going to write something about java.math.BigDecimal object usage. Let me explain the scenario here, so that you can understand the issue better. Since it is International payment, customer is free to select the payment currency from the list of available currencies to express the payment amount. Something likes 100.00 USD OR 50.00 GBP OR 34.98 EUR etc. As per the application design, we should not store the payment amount with decimals. We should store only in long values; we used to convert the payment amount based on currency decimal places. Ie 100.00 USD will be stored as 10000, 34.98 EUR will be stored as 3498, 45 JPY will be stored as 45 and 45.985 KWD will be stored as 45985 in payment amount column. If you see closely look these, the payment currencies are ISO currency codes which has it’s own currency decimal places to be allowed (For currencies like INR, GBP, USD, EUR you can have currency decimals maximum of 2 and all Dinars currency decimals maximum of 3 and for JPY no currency decimals to represent the payment amount).

We used movePointRight method available in java.math.BigDecimal to perform the above mentioned logic. Unfortunately my input type is primitive double which returns incorrect result. To add more details, if I pass payment amount as 77.80(double value) to the movePointRight method, it returns 77.79 (we were loosing one final decimal value). One of our UAT meetings, the user raised a concern asking how they are loosing ‘one cent’ if they enter payment amount as 77.8 EUR. When we debug the code, realized there was wrong amount conversion was happening if we use movePointRight method available in BigDecimal class for double/float arguments. We have written our own code to address this issue. But this issue can be addressed in a simple way. Ie, if we pass payment amount as string value to the movePointRight method it works fine.

Mentioned issue is clearly explained form the below mentioned example. You can run this program to get more information.


/*

* File: JavaDecimalBug.java

* Created/Last updated Date: Feb 7, 2012

* Created/Last updated by: Blx

* Last updated Time: 10:30:33 PM

* Copyright: BLX

*

* Revision History:

*******************************************************************

* Date Author Version Comments

*------------------------------------------------------------------

*

*/

package com.blx.laern.java.bug;

import java.math.BigDecimal;

/**

* @author Nanjundan Chinnasamy

* @version 1.0

*

*/

public class JavaDecimalBug {

/**

*

* @param value

* @param points

* @return

*/

private static long convertDecimalToLongByPoints(double value, int points) {

BigDecimal amountBD = new BigDecimal(value);

return amountBD.movePointRight(points).longValue();

}

/**

*

* @param value

* @param points

* @return

*/

private static long convertDecimalToLongByPoints(String value, int points) {

BigDecimal amountBD = new BigDecimal(value);

return amountBD.movePointRight(points).longValue();

}

/**

*

* @param args

*/

public static void main(String[] args) {

double paymentAmountInDub = 77.8;// 77.88, 77.97

String paymentAmountInStr = String.valueOf(paymentAmountInDub);

System.out.println(convertDecimalToLongByPoints(paymentAmountInDub, 2));

System.out.println(convertDecimalToLongByPoints(paymentAmountInStr, 2));

}

}


Result:

7779

7780


Pega Decisioning Consultant - Mission Test Quiz & Answers

The Pega Certified Decisioning Consultant (PCDC) certification is for professionals participating in the design and development of a Pega ...