decimal.js icon indicating copy to clipboard operation
decimal.js copied to clipboard

Using comparison operators with Decimals can give the wrong result

Open kynan opened this issue 3 years ago • 4 comments

The following behavior is somewhat confusing:

const { Decimal } = require('decimal.js');
five = new Decimal(5);
ten = new Decimal(10);
five < ten   // false
five <= ten  // false
ten > five   // false
ten >= five  // false

I'm aware there's dedicated comparison operators, but why does "elementary" comparison give the wrong result in this case?

kynan avatar Mar 31 '21 20:03 kynan

The relational operators cause valueOf to be called on each Decimal, which returns string values which are then compared 'alphabetically', and '5' comes after '1'.

MikeMcl avatar Mar 31 '21 22:03 MikeMcl

That does indeed make a lot of sense, thanks for the explanation! The joys of lexicographic comparison. And of course you can't have valueOf return a numeric value as that may lose precision.

Worth mentioning this in the docs as a caveat?

kynan avatar Apr 02 '21 12:04 kynan

As I did recently with big.js, in the next major release I may throw on calls to valueOf to prevent accidental usage of Decimals with arithmetic and relational operators.

MikeMcl avatar Apr 02 '21 18:04 MikeMcl

That's even better, as people don't read documentation :)

kynan avatar Apr 03 '21 14:04 kynan