## Why is [427.14 + 61.02 != 488.16] in double and how to do it in correct way?

Followings are some scenarios that I experienced and information that I found in The need for BigDecimal by John Zukowski and StackOverFlow posts.

The BigDecimal class stores floating-point numbers with practically unlimited precision. To manipulate the data, you call the add(value), subtract(value), multiply(value), or divide(value, scale, roundingMode)methods.

To output `BigDecimal`

values, set the scale and rounding mode with `setScale(scale, roundingMode)`

, or use either the `toString()`

or `toPlainString()`

methods. The `toString()`

method may use scientific notation while`toPlainString()`

never will.

Available roundingMode enumerations

`CEILING`

which always rounds towards positive infinity`DOWN`

which always rounds towards zero`FLOOR`

which always rounds towards negative infinity`UP`

which always rounds away from zero- HALF_DOWN which always rounds towards nearest neighbor, unless both neighbors are equidistant, in which case it rounds down
`HALF_UP`

which always rounds towards nearest neighbor, unless both neighbors are equidistant, in which case it rounds up`UNNECESSARY`

which asserts exact result, with no rounding necessary

Don’t create a BigDecimal from a primitive type like this.

double dd = .35; BigDecimal d = new BigDecimal(dd); // here d = .34999999999999997779553950749686919152736663818359375

Instead create a BigDecimal as follows

BigDecimal d = new BigDecimal(".35");

After creating the value, you can explicitly set the scale of the number and its rounding mode with setScale(). Like other Number subclasses in the Java platform, BigDecimal is immutable, so if you call setScale(), you must “save” the return value:

d = d.setScale(2, RoundingMode.HALF_UP);

Example :

package floatingPoints; import java.math.BigDecimal; public class TestingFloatingPoints { public static void main(String[] args) { TestingFloatingPoints testingFloatingPoints = new TestingFloatingPoints(); testingFloatingPoints.floatingPointsInDouble(); testingFloatingPoints.floatingPointsInBigDecimle(); } private void floatingPointsInDouble() { double total = 427.14; double tax = 61.02; double taxedTotal = tax + total; // This is 488.15999999999997 } private void floatingPointsInBigDecimle() { BigDecimal total = new BigDecimal("427.14"); BigDecimal tax = new BigDecimal("61.02"); BigDecimal taxedTotal = total.add(tax); // This is 488.16 } }

According to the Peter Lawry, The exact reason is that you get a number slightly less than you expect is that 427.14 is actually 427.1399999999999863575794734060764312744140625 and 61.02 is actually 61.02000000000000312638803734444081783294677734375 and when you add these together you get the nearest double value to 488.15999999999998948396751075051724910736083984375 which is slightly less than you expected. If you round this to 2 decimal places you get the expected answer 488.16

You can check the corresponding binary value for each floating point number by using binaryconvert.com.

Another comment for floating point numbers in StackOverFlow

Remember, a decimal value can not be represented exactly in a computer” It can, it just isn’t in IEEE 754 floating point. – T.J. Crowder

It can, if you have infinite memory. In a practical sense, and for the general case, it can’t. – Óscar López

@ Óscar: No, that’s not true at all. It’s just a matter of how many decimal places you want to hold. Or more accurately, how many significant digits you want. To get about the same range as a double but with perfect decimal accuracy, you only need about 56 significant digits and an indicator of where the decimal point goes. Of course, decimal numbers have their own issues, such as not being able to accurately store 1 / 3. 😉 – T.J. Crowder

###### Related articles

- the_need_for_bigdecimal (blogs.oracle.com)
- Java:Why should we use BigDecimal instead of Double in the real world?(StackOverFlow)
- What Every Computer Scientist Should Know About Floating-Point Arithmetic (blogs.oracle.com)
- How to resolve a Java Rounding Double issue (StackOverFlow)
- Why not allow double/decimal implicit conversions? (ericlippert.com)
- Addition of 16-bit Floating point Numbers and How to convert it back to decimal (stackoverflow.com)

## Leave a Reply