# Strange BigDecimal result

**URL:** <https://discuss.kotlinlang.org/t/strange-bigdecimal-result/26718>\
**Category:** Language Design\
**Created:** [April 21, 2023, 6:05am UTC](https://discuss.kotlinlang.org/t/strange-bigdecimal-result/26718 "2023-04-21T06:05:20Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![inemtsev](https://avatars.discourse-cdn.com/v4/letter/i/7ba0ec/32.png) [@inemtsev](https://discuss.kotlinlang.org/u/inemtsev)\
**Post date:** [April 21, 2023, 6:05am UTC](https://discuss.kotlinlang.org/t/strange-bigdecimal-result/26718/1 "2023-04-21T06:05:20Z")

</div>

Hello friends,

I am a bit confused at this behavior of BigDecimal, maybe someone has insight.

When I compare:  
` java.math.BigDecimal(0) == java.math.BigDecimal(0.00) // true`  
However, when I compare:  
`java.math.BigDecimal(0) == (0.00).toBigDecimal() // false`

Why is there a difference when converting from Double? I see that the standard library first converts double to String before making it a BigDecimal. Can this be why? And why convert it to String first??

---

<div class="post-metadata">

**Author:** ![raphael.tarita](https://avatars.discourse-cdn.com/v4/letter/r/3ab097/32.png) [@raphael.tarita](https://discuss.kotlinlang.org/u/raphael.tarita)\
**Post date:** [April 21, 2023, 7:22am UTC](https://discuss.kotlinlang.org/t/strange-bigdecimal-result/26718/2 "2023-04-21T07:22:57Z")

</div>

It really depends on your definition, but `BigDecimal#equals()` is pretty much broken because it also checks the internal `scale` field. Therefore two `BigDecimal`s can appear to not equal each other (by `equals()`) although they _mathematically_ represent exactly the same number. This is why you should never use `BigDecimal#equals()` (unless you know exactly what you’re doing and comparing the scale is something you actually wanna do, for whatever reason) and use `BigDecimal#compareTo()` instead. This function will behave as you’d expect it mathematically regarding equality (just check if the result is 0, then the two values are the same). Ironically, the JavaDoc for the `Comparable` interface says that the `compareTo()` implementation should ideally always align with the `equals()` implementation, which is not the case for `BigDecimal`s

Another remark here is that you should never initialize `BigDecimal`s with `Double`s as long as possible, especially in cases where the initialization is a literal. `Double`s always come with an inherent inaccuracy (for example, you cannot accurately represent the decimal value 0.1 with a binary floating-point data type). Therefore if you initialize a `BigDecimal` with a `Double` literal, chances are your `BigDecimal` will carry inaccuracy from the very beginning (which you probably wanted to avoid _by_ using `BigDecimal`). Therefore you should always initialize your `BigDecimal`s with strings, as the `BigDecimal` class can correctly convert a string into a numeric value without any inaccurate floating-point representations.

---

<div class="post-metadata">

**Author:** ![jbonzo](https://avatars.discourse-cdn.com/v4/letter/j/8e7dd6/32.png) [@jbonzo](https://discuss.kotlinlang.org/u/jbonzo)\
**Post date:** [April 27, 2023, 4:16pm UTC](https://discuss.kotlinlang.org/t/strange-bigdecimal-result/26718/3 "2023-04-27T16:16:48Z")

</div>

> [@raphael.tarita](#):
>
> you should never initialize `BigDecimal`s with `Double`s as long as possible, especially in cases where the initialization is a literal

If you look at the implementation of `BigDecimal`, the `valueOf(double)` function returns `new BigDecimal(Double.toString(val))`. So in that case it would return the same as creating a `BigDecimal` from a `String`. In the case of using the constructor `new BigDecimal(double)`, what you said is true.

Trying it with `jshell` gives me this:

```auto
jshell> import java.math.*

jshell> BigDecimal.valueOf(0.1)
$2 ==> 0.1

jshell> new BigDecimal(0.1)
$3 ==> 0.1000000000000000055511151231257827021181583404541015625

```

So if you’re creating a `BigDecimal` from a `double` literal, use the `valueOf` function to avoid issues.
