MikeMcl / decimal.js

An arbitrary-precision Decimal type for JavaScript
http://mikemcl.github.io/decimal.js
MIT License
6.35k stars 480 forks source link

toFixed() is inconsistent in some way #223

Closed korkis closed 1 year ago

korkis commented 1 year ago

new Decimal(‐0.0).toFixed(1) // 0.0 new Decimal(-0.01).toFixed(1) // -0.0

I think both should be 0.0

MikeMcl commented 1 year ago

The behaviour is intentionally consistent with JavaScript numbers and toFixed:

console.log((-0).toFixed(1));        // 0.0
console.log((-0.01).toFixed(1));     // -0.0
korkis commented 1 year ago

Javascript is weird. I think decimal.js is similar to Java's BigDecimal. This is Java's BigDecimal behavior. As far as I know, -0 is not used in the real world.

BigDecimal b1 = new BigDecimal("-0.0");
System.out.println(b1.setScale(1, RoundingMode.HALF_UP));// 0.0

BigDecimal b2 = new BigDecimal("-0.01");
System.out.println(b2.setScale(1, RoundingMode.HALF_UP));// 0.0
MikeMcl commented 1 year ago

Negative zero can signify that the sign of a number that underflowed to zero was negative, and toFixed retains the sign similarly.

const isNegativeZero = n => n === 0 && 1 / n === -1 / 0;
console.log(isNegativeZero(Number.MIN_VALUE/2));   // false
console.log(isNegativeZero(-Number.MIN_VALUE/2));  // true

See Why is negative zero important?.

But, yes, I have removed signed zero in an updated version of decimal.js that I hope to publish soon as a separate package.