MikeMcl / bignumber.js

A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic
http://mikemcl.github.io/bignumber.js
MIT License
6.63k stars 743 forks source link

Division on exponential values leads to infinite loop #347

Closed sfc-gh-aananthanarayanan closed 1 year ago

sfc-gh-aananthanarayanan commented 1 year ago

TL;DR - .div API on BigNumber instance on very small numbers leads to infinite loop.

Example code:

let num = new BigNumber(1e-20);

for(let i = 0; i< 1000 ; i++) {
    num = num.div(2);
}

console.log('number: ', num.toString());

At the end the loop num is still 1e-20. Expected (new BigNumber(1e-20)).div(2) to be 5e-21.

Is this expected? If so apart from having circuit breakers on loops is there any other safe way to end this?

shuckster commented 1 year ago

What's your DECIMAL_PLACES setting?

sfc-gh-aananthanarayanan commented 1 year ago

BigNumber.set({ DECIMAL_PLACES: 308 });

Right now it is set to 308

MikeMcl commented 1 year ago

If it was set to 308 before the loop you would end up with 1e-308, if it was set to 20 you would end up with 1e-20.

Note that 5e-21 rounded to 20 decimal places using rounding mode HALF_UP is 1e-20.

Just make sure your DECIMAL_PLACES setting is high enough.

BigNumber.set({ DECIMAL_PLACES: 25 });
console.log(BigNumber(1e-20).div(2).toString());    // '5e-21'