MikeMcl / bignumber.js

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

fromFormat as the opposite to toFormat #286

Open claudemartin opened 3 years ago

claudemartin commented 3 years ago

I can't find an easy way to parse a string that was created using toFormat. I'd like to see a fromFormat function that does that (based on current configuration) and additionally an option to configure BigNumber to automatically parse the strings passed to the constructor. Something like this: BigNumber.config({ AUTO_PARSE: true });

Does this exist yet? In my case this is only about ignoring the groupSeparator and reading decimalSeparator as '.'. But it would also have to handle everything else in BigNumber.Format.

shuckster commented 3 years ago

Does this work for you?

function removeFormatting ({ fromNumberString, withDecimalPoint = '.' }) {
  const rx = new RegExp(`[^${withDecimalPoint}\\d]*`, 'g')
  return fromNumberString.replace(rx, '')
}

removeFormatting({ fromNumberString: '123 456 789.12345 6789' })
// 123456789.123456789

It works by creating a regular-expression that removes everything that isn't a digit or a decimal-point.

MikeMcl commented 3 years ago

I don't want to enhance the BigNumber constructor so it can handle toFormat strings, but following shuckster a fromFormat function could be added using, for example

// Assumes '-' is only used as a minus sign.
BigNumber.fromFormat = (stringFromToFormat, formatObject) => {
  const sep = formatObject.decimalSeparator;
  const str = stringFromToFormat.replace(new RegExp(`[^${sep || '.'}\\d-]+`, 'g'), '');
  return new BigNumber(sep ? str.replace(sep, '.') : str); 
};  

(If this function was internal to the library then obviously it would have access to the global FORMAT object and so it wouldn't need to be passed in.)

claudemartin commented 3 years ago

I agree that the constructor doesn't need to be changed. But a fromFormat like this would be nice. Note it should also allow e as in BigNumber.fromFormat("1e-3") and everything in ALPHABET. And then there's ±Infinity and NaN. It should be able to handle anything that toFormat could possibly return but also everything the constructor would allow. Pre- and suffix could be removed to prevent problems with them containing digits, especially in combination with a custom alphabet.

povilass commented 1 year ago

probably should be called fromFormat -> parse parse('1000.000-e', {format: '', groupSeparator, ...etc}) parse('1000.000-e')