Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BigDecimal in Java

I am thinking of using BigDecimal to compare two currency values rounded to 2 digits. For example I expect the following to yield 0 because I'm comparing something that should round to 0.02 with something that is 0.02. But it yields -1 !! Is there a right way to do this?

This should also work for larger numbers like 123.45 vs 123.4534 ... which should yield 0 when "compareTo" is used.

I've tried using math context but it doesnt seem elegant ... is there a correct way?

BigDecimal spread = new BigDecimal(0.01934);
spread.setScale(2, RoundingMode.HALF_EVEN);
System.out.format("0.0193 ? 0.02 = %d\n", spread.compareTo(new BigDecimal(0.02)));

AND THE SOLUTION IS:

BigDecimal spread = new BigDecimal(0.01934).setScale(2, RoundingMode.HALF_EVEN);
BigDecimal loSpread = new BigDecimal(0.02).setScale(2, RoundingMode.HALF_EVEN);
System.out.format("0.0193 ? 0.02 = %d\n", spread.compareTo(loSpread));
like image 501
fodon Avatar asked Jun 24 '12 01:06

fodon


People also ask

Why do we use BigDecimal in Java?

Java's BigDecimal has the additional advantage that it can have an arbitrary (but finite) number of digits on both sides of the decimal point, limited only by the available memory.

What is the difference between double and BigDecimal in Java?

1 Answer. A BigDecimal is an accurate way of expressing numbers. A Double has a reliable accuracy. Going with doubles of various magnitudes (say d1=1000.0 and d2=0.001) could occur in the 0.001 being dropped collectively when summing as the variation in magnitude is so large.

Where can I use BigDecimal?

The BigDecimal class provides operations on double numbers for arithmetic, scale handling, rounding, comparison, format conversion and hashing. It can handle very large and very small floating point numbers with great precision but compensating with the time complexity a bit.

How do I set big decimal value?

math. BigDecimal. valueOf(double val) is an inbuilt method in java that translates a double into a BigDecimal, using the double's canonical string representation provided by the Double. toString(double) method.


1 Answers

First off, BigDecimal is immutable. You must return the result from your setScale method call:

spread = spread.setScale(2, RoundingMode.HALF_EVEN);

Next you must improve your accuracy of the second BigDecimal since it is being derived from a double -- not a very accurate entity. So try a String:

 spread.compareTo(new BigDecimal("0.02"))
like image 132
Hovercraft Full Of Eels Avatar answered Sep 23 '22 10:09

Hovercraft Full Of Eels