Stage 1
Classification: API Change
Human Validated: KW
Title: {BigInt,Number}.fromString
Authors: Mathias Bynens
Champions: Mathias Bynens
Last Presented: January 2018
Stage Upgrades:
Stage 1: 2018-03-21
Stage 2: NA
Stage 2.7: NA
Stage 3: NA
Stage 4: NA
Last Commit: 2018-03-21
Topics: numbers others
Keywords: bigint numeric string
GitHub Link: https://github.com/tc39/proposal-number-fromstring
GitHub Note Link: https://github.com/tc39/notes/blob/HEAD/meetings/2018-01/jan-23.md#13iic-bigintnumberfromstring-for-stage-1
Proposal Description:
ECMAScript proposal: {BigInt,Number}.fromString
Status
This proposal is at stage 1 of the TC39 process.
Background
The BigInt proposal initially included a static BigInt.parseInt method. After some discussion, it was removed in favor of a separate proposal to add a static fromString method to both BigInt and Number. This is that proposal.
Motivation
{BigInt,Number}.prototype.toString(radix) enables converting a numeric value into a string representation of that value. For BigInts specifically, there is currently no built-in way to do the inverse, i.e. to turn a string representation of a BigInt with a given radix back into a BigInt.
For Number values, there is parseInt(string, radix = 10) and Number.parseInt(string, radix = 10), but its behavior is suboptimal:
- It returns
NaNinstead of throwing aSyntaxErrorexception whenstringdoes not represent a number. - It returns
NaNinstead of throwing aRangeErrorexception whenradixis not valid (i.e.radix !== 0 && radix < 2orradix > 36). - It accepts radix
0, treating it as10instead, which does not make sense. - It ignores leading whitespace and trailing non-digit characters.
- It supports hexadecimal integer literal prefixes
0xand0Xbut lacks support for octal integer literal prefixes0oand0Oor binary integer literal prefixes0band0B, which is inconsistent. - The fact that
parseInthas some level of support for integer literal prefixes means that it’s not a clear counterpart totoString.
Proposed solution
We propose extending both BigInt and Number with a new static fromString(string, radix = 10) method which acts as the inverse of {BigInt,Number}.prototype.toString(radix = 10). It accepts only strings that can be produced by {BigInt,Number}.prototype.toString(radix = 10), and throws an exception for any other input.
High-level API
Number.fromString('42');
// → 42
Number.fromString('42', 10);
// → 42
BigInt.fromString('42');
// → 42n
BigInt.fromString('42', 10);
// → 42nIllustrative examples
The following examples use Number.fromString. The semantics for BigInt.fromString are identical except it returns a BigInt rather than a Number.
Unlike parseInt, fromString intentionally lacks special handling for integer literal prefixes.
Number.parseInt('0xc0ffee');
// → 12648430
Number.parseInt('0o755');
// → 0
Number.parseInt('0b00101010');
// → 0
Number.fromString('0xc0ffee');
// → SyntaxError
Number.fromString('0o755');
// → SyntaxError
Number.fromString('0b00101010');
// → SyntaxError
Number.fromString('C0FFEE', 16);
// → SyntaxError (toString produces lowercase digits)
Number.fromString('c0ffee', 16);
// → 12648430 === 0xc0ffee
Number.fromString('755', 8);
// → 493 === 0o755
Number.fromString('00101010', 2);
// → 42 === 0b00101010Unlike parseInt, fromString throws a SyntaxError exception when string does not represent a number.
Number.parseInt('');
// → NaN
Number.parseInt(' \n ');
// → NaN
Number.parseInt('x');
// → NaN
Number.fromString('');
// → SyntaxError
Number.fromString(' \n ');
// → SyntaxError
Number.fromString('x');
// → SyntaxErrorUnlike parseInt, fromString throws a RangeError exception when radix < 2 or radix > 36.
Number.parseInt('1234', 0);
// → 1234
Number.parseInt('1234', 1);
// → NaN
Number.parseInt('1234', 37);
// → NaN
Number.fromString('1234', 0);
// → RangeError
Number.fromString('1234', 1);
// → RangeError
Number.fromString('1234', 37);
// → RangeErrorUnlike parseInt, fromString throws a TypeError exception when string is not a string.
Number.parseInt(true, 32);
// → 978894
Number.fromString(true, 32);
// → TypeErrorFAQ
What about legacy octal integers?
fromString intentionally lacks special handling for legacy octal integer literals, i.e. those without the explicit 0o or 0O prefix such as 010. In other words, Number.fromString('010') throws a SyntaxError exception.
What about numeric separators?
fromString does not need to support numeric separators, as they cannot occur in {BigInt,Number}.prototype.toString(radix) output. Number.fromString('1_000_000_000') throws a SyntaxError exception.
Does BigInt.fromString(string) support the n suffix?
BigInt.fromString does not need to support the n suffix used for BigInt literals, as it doesn’t occur in BigInt.prototype.toString(radix) output. Furthermore, supporting it would introduce an ambiguity for radices where n is a valid digit: should BigInt.fromString('1n', 32) return 1 or 55? With the current proposal, BigInt.fromString('1n', 32) returns 55, and BigInt.fromString('1n') throws a SyntaxError exception.
Specification
Implementations
- none yet