barbosa - 6 months ago 25

Java Question

I started using Sonar recently in a project, and i got a PMD rule broken about using the constructor

`new BigDecimal(double val)`

`new BigDecimal(String val)`

Here is what javadoc says for

`BigDecimal`

`public BigDecimal(double val)`

Translates a double into a BigDecimal which is the exact decimal

representation of the double's binary floating-point value. The scale

of the returned BigDecimal is the smallest value such that (10scale ×

val) is an integer.

Notes:

The results of this constructor can be somewhat unpredictable. One

might assume that writingin Java creates a`new BigDecimal(0.1)`

which is exactly equal to 0.1 (an unscaled value of 1,`BigDecimal`

with a scale of 1), but it is actually equal to

0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that

matter, as a binary fraction of any finite length). Thus, the value

that is being passed in to the constructor is not exactly equal to

0.1, appearances notwithstanding.

The String constructor, on the other hand, is perfectly predictable:

writingcreates a`new BigDecimal("0.1")`

which is`BigDecimal`

exactly equal to 0.1, as one would expect. Therefore, it is generally

recommended that the String constructor be used in preference to this

one.

When a double must be used as a source for a, note that`BigDecimal`

this constructor provides an exact conversion; it does not give the

same result as converting the double to a String using the

method and then using the`Double.toString(double)`

constructor. To get that result, use the static`BigDecimal(String)`

method.`valueOf(double)`

Why does this constructor really exists? Isnt

`new BigDecimal(String val)`

`new BigDecimal(double val)`

Answer

Why does this constructor really exists?

It converts the actual represented value of `double`

to a BigDecimal. The whole point of BigDecimal is to give as much precision as possible and that is what this constructor does.

If you want to take the value you would get with a small amount of rounding the `Double.toString(double)`

uses you can use

```
System.out.println(BigDecimal.valueOf(0.1));
```

prints

```
0.1
```

When should I use the new BigDecimal(double val) constructor

When you want to know the value `double`

really represents. You can apply your own rounding as required.

When you use `double`

you should always apply a sensible rounding. But, if you did that you may find you don't need BigDecimal. ;)