How to do Arithmetic Operations with Exact Precision (Decimal Points) in Java

While doing arithmetic operations with "float" and "double", you might have observed inconsistent results. Following is an example.

public class Test 
{
	public static void main(String[] args) 
	{
		float a = 24567.566f;
		
		float b = 43f;
		
		System.out.println("" + a*b);
	}
}

The above program will produce a result of "1056405.4" on the console. But if you do the multiplication on a calculator, you will get the result as "1056405.338". The results are not matching even if you round it to single precision.

This kind of error or inconsistency is not acceptable if you do programing for a financial application or if you want precise results up to many decimal points and you want the results to be the same where ever you execute the program (ie. machine independent)

The official java doc says the following about float and double primitive types.

float: The float data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in section 4.2.3 of the Java Language Specification. As with the recommendations for byte and short, use a float (instead of double) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency. For that, you will need to use the java.math.BigDecimal class instead. Numbers and Strings covers BigDecimal and other useful classes provided by the Java platform

double: The double data type is a double-precision 64-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in section 4.2.3 of the Java Language Specification. For decimal values, this data type is generally the default choice. As mentioned above, this data type should never be used for precise values, such as currency.

So "float" will guarantee you results up to one decimal point and "double" will guarantee you results up to two decimal points. If you want to have precision of more than 2 decimal points you need to use "BigDecimal". Following is an example which uses BigDecimal.

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

public class Test 
{
	public static void main(String[] args) 
	{
		//Initializing variables
		BigDecimal a = new BigDecimal(24567.566);
		BigDecimal b = new BigDecimal(43);
		
		//doing multiplication
		BigDecimal c = a.multiply(b);
		
		//Printing with full precision
		System.out.println("" + c.toPlainString());
		
		//Rounding value to 3 decimal points
		c = c.setScale(3, RoundingMode.HALF_UP);
		
		//Print the rounded value
		System.out.println("" + c.toPlainString());
		
		//Saving Bigdecimal value to database
		//PreparedStatement ps = null;
		//ps.setBigDecimal(1, c);
	}
}

The above example shows how to declare a BigDecimal, how to do arithmetic operations, How to do rounding and printing/saving the decimal value.

Powered by Bullraider.com