|
@@ -75,6 +75,10 @@ export const stringify = < |
|
|
throw new TypeError(`Value must be a string, number, or bigint. Received: ${typeof value}`); |
|
|
throw new TypeError(`Value must be a string, number, or bigint. Received: ${typeof value}`); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (typeof value === 'number' && Number.isNaN(value)) { |
|
|
|
|
|
return 'NaN'; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const valueStr = value.toString().replace(/\s/g, ''); |
|
|
const valueStr = value.toString().replace(/\s/g, ''); |
|
|
const { system = enUS.shortCount, stringifyGroupsOptions, mergeTokensOptions } = options; |
|
|
const { system = enUS.shortCount, stringifyGroupsOptions, mergeTokensOptions } = options; |
|
|
|
|
|
|
|
@@ -110,7 +114,16 @@ export interface ParseOptions { |
|
|
* @returns AllowedValue The numeric equivalent of the value. |
|
|
* @returns AllowedValue The numeric equivalent of the value. |
|
|
*/ |
|
|
*/ |
|
|
export const parse = (value: string, options = {} as ParseOptions) => { |
|
|
export const parse = (value: string, options = {} as ParseOptions) => { |
|
|
const { system = enUS.shortCount, type = 'string' } = options; |
|
|
|
|
|
|
|
|
const { system = enUS.shortCount, type: typeRaw = 'string' } = options; |
|
|
|
|
|
const type = typeRaw.trim().toLowerCase() as ParseResult; |
|
|
|
|
|
|
|
|
|
|
|
if (!((ALLOWED_PARSE_RESULT_TYPES as unknown as string[]).includes(type))) { |
|
|
|
|
|
throw new TypeError(`Return type must be a string, number, or bigint. Received: ${type}`); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (value.trim().toLowerCase() === 'nan') { |
|
|
|
|
|
return type === 'number' ? NaN : 'NaN'; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const tokens = system.tokenize(value); |
|
|
const tokens = system.tokenize(value); |
|
|
const { groups, negative } = system.parseGroups(tokens); |
|
|
const { groups, negative } = system.parseGroups(tokens); |
|
@@ -124,6 +137,7 @@ export const parse = (value: string, options = {} as ParseOptions) => { |
|
|
const exponentValue = Number(exponent); |
|
|
const exponentValue = Number(exponent); |
|
|
const integerValue = Number(integer); |
|
|
const integerValue = Number(integer); |
|
|
|
|
|
|
|
|
|
|
|
// max safe integer: 9.007199254740991e+15 |
|
|
const [maxSafeIntegerSignificand, maxSafeIntegerExponent] = Number.MAX_SAFE_INTEGER.toExponential().split('e'); |
|
|
const [maxSafeIntegerSignificand, maxSafeIntegerExponent] = Number.MAX_SAFE_INTEGER.toExponential().split('e'); |
|
|
if ( |
|
|
if ( |
|
|
exponentValue >= Number(maxSafeIntegerExponent) |
|
|
exponentValue >= Number(maxSafeIntegerExponent) |
|
@@ -136,6 +150,7 @@ export const parse = (value: string, options = {} as ParseOptions) => { |
|
|
return stringValue; |
|
|
return stringValue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// epsilon: 2.220446049250313e-16 |
|
|
const [epsilonSignificand, epsilonExponent] = Number.EPSILON.toExponential().split('e'); |
|
|
const [epsilonSignificand, epsilonExponent] = Number.EPSILON.toExponential().split('e'); |
|
|
if ( |
|
|
if ( |
|
|
exponentValue <= Number(epsilonExponent) |
|
|
exponentValue <= Number(epsilonExponent) |
|
|