|
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import BigNumber from 'bignumber.js';
-
- const EXPONENT_SEPARATOR = 'e';
- const SIGNIFICAND_DECIMAL_POINT = '.';
-
- export const NEGATIVE_SIGN = '-';
-
- export const BLANK_DIGIT = '0'; // must be a value where Number(BLANK_DIGIT) === 0
-
- export type Numeric = number | bigint | string | BigNumber
-
- export type Group = [string, BigNumber]
-
- export const normalizeNumeric = (x: Numeric): string => {
- try {
- switch (typeof x) {
- case 'number':
- return new BigNumber(x).toString(10);
- case 'bigint':
- return x.toString(10);
- case 'string':
- // TODO assume not all strings follow a correct format
- return x.trim();
- // return new BigNumber(x).toString(10)
- case 'object':
- return x.toString(10);
- default:
- break;
- }
- } catch {
- throw new RangeError('Not a valid numeric value in the current locale.');
- }
- throw new TypeError('Not a valid numeric value in any locale.');
- };
-
- export const deconstructNumeric = (x: string) => {
- const absolute = x.replaceAll(NEGATIVE_SIGN, '');
- if (!absolute.includes(EXPONENT_SEPARATOR)) {
- return {
- exponent: new BigNumber(absolute.length - 1),
- significandDigits: absolute,
- };
- }
- const [significandStrExp, exponentStr] = absolute.split(EXPONENT_SEPARATOR);
- const [integral] = significandStrExp.split(SIGNIFICAND_DECIMAL_POINT);
- return {
- exponent: new BigNumber(exponentStr).plus(integral.length - 1),
- significandDigits: significandStrExp.replaceAll(SIGNIFICAND_DECIMAL_POINT, ''),
- };
- };
-
- export const createBlankDigits = (grouping: number) => new Array<string>(grouping).fill(BLANK_DIGIT).join('');
-
- export const groupDigits = (significandStr: string, exponent: BigNumber, grouping: number) => {
- const blankDigits = createBlankDigits(grouping);
- return significandStr
- .split('')
- .reduceRight(
- (theGroups, c, i): any => {
- const currentGroupIndex = exponent.minus(i).dividedToIntegerBy(grouping).minus(1);
- const [lastGroup = [blankDigits, currentGroupIndex.plus(1)] as Group] = theGroups;
- const [digits, groupIndex] = lastGroup;
- const currentPlaceValue = exponent.minus(i).mod(grouping);
- if (currentPlaceValue.eq(0)) {
- return [[`${blankDigits.slice(0, -c.length)}${c}`, currentGroupIndex.plus(1)], ...theGroups];
- }
- const currentDigitStringIndex = new BigNumber(grouping).minus(1).minus(currentPlaceValue).toNumber();
- const newDigits = digits.slice(
- 0,
- currentDigitStringIndex,
- ) + c + digits.slice(currentDigitStringIndex + c.length);
- return [[newDigits, groupIndex] as Group, ...theGroups.slice(1)];
- },
- [] as Group[],
- );
- };
|