Working with Java BigDecimal class for monetary values
When you are working with monetary values in Java, you must use a BigDecimal data type. Many developers often have the following questions.
Q1. How to compare BigDecimal numerically?
This means 5.120 should be equal to 5.1200000. The default equals( ) implementation in BigDecimal class returns true only if two objects are numerically equivalent AND have the same scale(i.e. 5.120 is not equals( ) to 5.1200000).
Q2. How to check if an amount is zero, positive, or negative?
Q3. How to extract the decimal portion of the amount?
Q4. How to determine if it is an integer value?
Here is a utility class that answers the above questions
package com.writtentest10; import java.math.BigDecimal; public class BigDecimalUtils { private BigDecimalUtils() { } /** * The 'equals' method in BigDecimal class returns true * only if the two objects are numerically equivalent AND * have the same scale so (4.130 != 4.130000000) * * This method returns true if the two values are numerically equivalent * */ public static boolean equals(BigDecimal value1, BigDecimal value2) { return (value1.compareTo(value2) == 0); } public static boolean isZero(BigDecimal value) { return (value.signum() == 0); } public static boolean isNonZero(BigDecimal value) { return (value.signum() != 0); } public static boolean isPositive(BigDecimal value) { return (value.signum() == 1); } public static boolean isNegative(BigDecimal value) { return (value.signum() == -1); } public static BigDecimal getExponent(BigDecimal value) { return BigDecimal.valueOf(value.longValue()); } public static BigDecimal getMantissa(BigDecimal value) { if (isZero(value)) { return value; } BigDecimal result = value.abs(); BigDecimal exponent = getExponent(result); if (isZero(exponent)) { return result; } return result.subtract(exponent); } public static boolean isInteger(BigDecimal value) { return isZero(value) ? false : isZero(getMantissa(value)); } }
The JUnit test class
package com.writtentest10; import java.math.BigDecimal; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class BigDecimalUtilsTest { private boolean setUpIsDone = false; private BigDecimal positiveValue1; private BigDecimal positiveValue2; private BigDecimal negativeValue; @Before public void init() { if (setUpIsDone) { return; } positiveValue1 = BigDecimal.valueOf(25.12); positiveValue2 = BigDecimal.valueOf(25.1200); negativeValue = BigDecimal.valueOf(-25.12); setUpIsDone = true; } @Test public void testEqual() { Assert.assertTrue(BigDecimalUtils.equals(positiveValue1, positiveValue2)); Assert.assertFalse(BigDecimalUtils.equals(positiveValue1, negativeValue)); } @Test public void testPositiveNegativeAndZero() { Assert.assertTrue(BigDecimalUtils.isPositive(positiveValue1)); Assert.assertTrue(BigDecimalUtils.isNegative(negativeValue)); Assert.assertTrue(BigDecimalUtils.isZero(BigDecimal.ZERO)); Assert.assertFalse(BigDecimalUtils.isPositive(negativeValue)); Assert.assertFalse(BigDecimalUtils.isNegative(positiveValue1)); Assert.assertFalse(BigDecimalUtils.isZero(positiveValue1)); } @Test public void testGetMantissa() { Assert.assertEquals(BigDecimal.valueOf(0.12),BigDecimalUtils.getMantissa(positiveValue1)); Assert.assertEquals(BigDecimal.valueOf(0.12),BigDecimalUtils.getMantissa(positiveValue2)); Assert.assertEquals(BigDecimal.valueOf(0.12),BigDecimalUtils.getMantissa(negativeValue)); } @Test public void testIsInteger() { Assert.assertFalse(BigDecimalUtils.isInteger(positiveValue1)); Assert.assertFalse(BigDecimalUtils.isInteger(negativeValue)); Assert.assertTrue(BigDecimalUtils.isInteger(BigDecimal.ONE)); Assert.assertFalse(BigDecimalUtils.isInteger(BigDecimal.ZERO)); Assert.assertTrue(BigDecimalUtils.isInteger(BigDecimal.valueOf(12.00))); } }
Here is a real life example of using BigDecimal for monetary calculation with design patterns.
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home