user1514499 - 2 years ago 108

Java Question

I tried the following code. but getting different result when subtracting using BigDecimal.

`double d1 = 0.1;`

double d2 = 0.1;

System.out.println("double result: "+ (d2-d1));

float f1 = 0.1F;

float f2 = 0.1F;

System.out.println("float result: "+ (f2-f1));

BigDecimal b1 = new BigDecimal(0.01);

BigDecimal b2 = new BigDecimal(0.01);

b1 = b1.subtract(b2);

System.out.println("BigDecimal result: "+ b1);

Result:

`double result: 0.0`

float result: 0.0

BigDecimal result: 0E-59

I am still working on this. can anyone please clarify.

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

Interesting, the values appear to be equal and subtraction does give you zero, it appears to just be an issue with the printing code. The following code:

```
import java.math.BigDecimal;
public class Test {
public static void main(String args[]) {
BigDecimal b1 = new BigDecimal(0.01);
BigDecimal b2 = new BigDecimal(0.01);
BigDecimal b3 = new BigDecimal(0);
if (b1.compareTo(b2) == 0) System.out.println("equal 1");
b1 = b1.subtract(b2);
if (b1.compareTo(b3) == 0) System.out.println("equal 2");
System.out.println("BigDecimal result: "+ b1);
}
}
```

outputs *both* `equal`

messages, indicating that the values **are** the same and that you get **zero** when you subtract.

You could try to raise this as a bug and see what Oracle comes back with. It's likely they'll just state that `0e-59`

is still zero, so not a bug, or that the rather complex behaviour being described on the BigDecimal documentation page is working as intended. Specifically, the point that states:

There is a one-to-one mapping between the distinguishable BigDecimal values and the result of this conversion. That is, every distinguishable BigDecimal value (unscaled value and scale) has a unique string representation as a result of using toString. If that string representation is converted back to a BigDecimal using the BigDecimal(String) constructor, then the original value will be recovered.

That fact that the original value needs to be recoverable means that `toString()`

needs to generate a unique string for each scale, which is why you're getting `0e-59`

. Otherwise, converting the string *back* to a `BigDecimal`

may give you a different value (unscaled-value/scale tuple).

If you really *want* zero to show up as "0" regardless of the scale, you can use something like:

```
if (b1.compareTo(BigDecimal.ZERO) == 0) b1 = new BigDecimal(0);
```

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**