## Float and double in Java "inaccurate" result

There is a well known problem with precise floating point numbers representation in a computer, and Java is no different in this case. If you want to see it for yourself, than try executing the below code:

```
Double d = new Double(4.395f);
System.out.println(d);
```

You might expect the **4.395** will be printed out, right? Well, you’re defining an “exact” number as a float (32 bit),
than casting it to the double (64 bit) so there should be no problem, as it shouldn’t affect the value.
After all it’s only 4.395 and **not** 4.3956312123540604, right? In the matter of fact, the result will be like this:

4.394999980926514

Not quite what you expected, huh? Well, going further, if you would try rounding this double value, using something like this:

```
NumberFormat nf = NumberFormat.getInstance();
// It means that 3.125 should be rounded to 3.13, and 3.123 to 3.12
nf.setRoundingMode(RoundingMode.HALF_UP);
nf.setMaximumFractionDigits(2);
System.out.println(nf.format(value));
```

Than you’ll end with a value of

**4.39**, instead of expected **4.40**. And this might cause even **bigger** problems in the future.
So, the advice is – if you are facing a problem of a double <-> float casting, financial operations or any other
floating-point sensitive operations, use BigDecimal
class. It will **save you a lot of time** trying to find where is the bug or even more **serious consequences** of so
written code. It saves the number which consists of unscaled integer value (32 bit) and scale integer value (also 32 bit)
and gives you a possibility to define the MathContext
which affects the held number, as well as the rounding mode. The above code can be rewritten to use the **BigDecimal** class, as follows:

```
/** Instantiate the BigDecimal class with given value. Note that
* there is no BigDecimal(float) constructor, hence the float
* value will be promoted to the double type and BigDecimal(double)
* will be executed ultimately.
*/
BigDecimal bd = new BigDecimal(4.395f);
/** Not setting the Rounding mode will result in throwing
* ArithemeticException, as the rounding is necessary in this
* case (remember it's the 4.394999980926514 double value).
* The BigDecimal is immutable, so this method doesn't affect the
* original object referenced by <strong>bd</strong> variable.
*/
bd = bd.setScale(3, RoundingMode.HALF_UP);
// When converting, the number represents the actual value.
double res3 = bd.doubleValue();
System.out.println(res3);
```

The result will be as expected (already rounded):

4.40

Note, that if you would like to get the original value, you could use this:

```
// Define we are interested in Decimal32 format.
BigDecimal bd = new BigDecimal(4.395f, MathContext.DECIMAL32);
double res3 = bd.doubleValue();
System.out.println(res3);
```

The result will be:

4.395

Just remember that the DECIMAL32 (or any other constant in MathContext) defines it’s RoundingMode!

You can also take a look at this discussion
or take a look at “Effective Java” by Joshua Bloch
(Second Edition) where you can read about this problem in *Chapter 8, Item 48: Avoid float and double if exact answers are required*.