(BigDecimal(“0E-8”) == BigDecimal.ZERO) - false

(BigDecimal(“0E-8”).compareTo(BigDecimal.ZERO) == 0) - true

(BigDecimal(“0E-8”) == BigDecimal.ZERO.setScale(8)) - true

Is it a bug?

(BigDecimal(“0E-8”) == BigDecimal.ZERO) - false

(BigDecimal(“0E-8”).compareTo(BigDecimal.ZERO) == 0) - true

(BigDecimal(“0E-8”) == BigDecimal.ZERO.setScale(8)) - true

Is it a bug?

New operators

The BigDecimal comparison functions are part of the JDK. Even if this behavior is a bug, it’s not a bug in Kotlin; you’ll see exactly the same with plain Java code.

Ah, so ==, <, > compares object references for BigDecimals in Kotlin?

But in this case (BigDecimal(“0E-8”) == BigDecimal.ZERO.setScale(8)) - should be false always not?

No. The `==`

operator is compiled into a call of `BigDecimal.equals()`

, and `<`

and `>`

are compiled into calls of `BigDecimal.compareTo()`

, like for any other object. Both `BigDecimal.equals()`

and `BigDecimal.compareTo()`

are implemented in the JDK, and if you see any inconsistency, that’s a problem with the JDK implementation.

Consequence of this is that you get the following:

val zero = BigDecimal(“0E-8”)

(zero < BigDecimal.ZERO) // false

(zero > BigDecimal.ZERO) // false

(zero == BigDecimal.ZERO) // false

For BigDecimals equals checks both value and scale. `d1.compareTo(d2) == 0`

produces correct result and probably would be more meaningful for `==`

operator.

I would think if an object implements Comparable, == should rather use compareTo. Expectation would be that < and > have the same semantics as ==

Both Scala and Groovy gives true for BigDecimal(“0E-8”) == BigDecimal.ZERO so looks like they do it this way…

FWIW, over the years there have been major user complaints arguing that Groovy should translate `==`

to `equals`

even for `Comparable`

types (e.g. https://issues.apache.org/jira/browse/GROOVY-3364).

IMO `==`

operator should be configurable. For most cases `equals`

is fine, but there are classes where `equals`

just doesn’t make sense as `==`

: `BigDecimal`

, `Array`

. There should be a way to alter default behaviour and call `compareTo()`

for `BigDecimal`

s, `Arrays.compare`

for Arrays, etc.

I’m not sure how you envision this configurability, especially in the presence of generic classes. It would be really weird to have == work differently for `t: T`

in `Foo<T>`

where T is BigDecimal and for `t: BigDecimal`

.

I agree, it would be strange. Probably no good solution for that. May be it’s worth to implement BigDecimal wrapper to overcome this problem, like Scala did,

I solve that problem using infix

```
infix fun BigDecimal.equalsTo(other: BigDecimal) = this.compareTo(other)==0
if(result equalsTo BigDecimal.ZERO){
}
```

On the other hand, consider adding something like the spaceship operator that checks compareTo. But the syntax would be really strange, and I can see lexer problems coming (isn’t `template<X<Y>>`

in C++ and `x: T<U>=m`

in kotlin already bad enough?)