tc39 / proposal-number-fromstring

{BigInt,Number}.fromString(string, radix)
https://mathiasbynens.github.io/proposal-number-fromstring/
65 stars 7 forks source link

What should this accept? #18

Open waldemarhorwat opened 6 years ago

waldemarhorwat commented 6 years ago

There are a number of inconsistencies here about what this method is supposed accept.

The proposal makes the following claim: "It accepts only ASCII-case-insensitive strings that can be produced by {BigInt,Number}.prototype.toString(radix = 10), and throws an exception for any other input."

This states that Number.fromString would throw on the input "-0", "007", or "999999999999999999999999999999999", whereas the proposed spec (correctly in my opinion) accepts those.

Conversely, this claims that Number.fromString would accept "0.5" and "Infinity", whereas the proposed spec bans those. It seems weird for something called "Number.fromString" to not accept numbers with a decimal point or other values that can be produced by Number's toString.

mathiasbynens commented 6 years ago

Conversely, this claims that Number.fromString would accept "0.5" and "Infinity", whereas the proposed spec bans those.

The intention is to support both the 0.5 and Infinity cases. I understand the current phrasing is vague (a problem inherited from the parseInt spec) and one could misinterpret Infinity. What makes you think the current spec would ban e.g. 0.5 though?

waldemarhorwat commented 6 years ago

The current spec doesn't accept decimal points. It also doesn't accept exponential notation; I'm not sure whether that's intentional or not.

mathiasbynens commented 6 years ago

Why not? It says:

If string represents a mathematical number value in radix-R notation, using the characters 0-9 for digits with values 0 to 9, and the letters A-Z and a-z for digits with values 10 through 35, then […]

Decimal points are arguably covered by “a mathematical number value in radix-R notation”.

The intention is to support everything that can be produced by toString.

waldemarhorwat commented 6 years ago

That's not a sound interpretation. The text only mentions the characters 0-9, A-Z, and a-z. Trying to construe it as anything that can be produced by toString leads to all kinds of problems:

mathiasbynens commented 6 years ago

That's not a sound interpretation. The text only mentions the characters 0-9, A-Z, and a-z.

It says to use those characters to represent the digits. It doesn’t say to only use those characters. 12.34 represents “a mathematical number value [in radix-R notation]”.

As stated before, we’re in agreement that this needs to be specified in a less hand-wavey way to avoid discussions like this.

Is "." a valid number?

Why would it be? Can Number#toString produce that?

I’d be interested in hearing your thoughts on how best to specify this, in case the committee agrees this proposal is worth pursuing. Any ideas?

tabatkins commented 6 years ago

Suggested full set:

For all forms, digits are limited only to those that are valid according to the base. All allow an optional leading "-" too, obvs.

Being like JSON is a nice rule, per Yehuda, and the non-base-10 setup is all of JSON that can be accepted without ambiguity.

waldemarhorwat commented 6 years ago

Many folks spell hexadecimal numbers using upper case, so I'd prefer accepting either case for bases >10. We can make an exception for mixed case "NaN" and "Infinity" in high bases, either treating those two strings specially, or disallowing all mixed-case high-base numerals. For decimal points, I feel that X. should be allowed too. . should not.

tabatkins commented 6 years ago

By ., do you mean literally . by itself? I agree, that shouldn't be allowed.

I'm not a fan of X. (and neither CSS nor JSON allow that form), but people have different opinions on this; I don't feel strongly. It's against the "what toString() outputs" principle, tho - toString will never output a trailing dot.

Allowing all-uppercase, while disallowing mixed-case (and then special-casing "Infinity"/"NaN"), seems like a reasonable compromise to me. Allowing mixed-case but treating "Infinity" specially is a very unappealing idea; v bad, imo, to have one particular base-35/36 number be unable to be parsed seems quite bad.

Slayer95 commented 5 years ago

Is "1e20" a valid number? In radix 10? In radix 12? In radix 15?

In Number.prototype.toString, scientific notation is only generated for radix 10 (underspecified [1][2][3], observed in Chrome), for values larger than 10^21, in the form 1e+21...

So 1e20 should be valid as a radix 15+ numeral, while 1e+21 should be valid in radix 10 (but should scientific notation be valid in other radixes?)

[1] 20.1.3.6 Number.prototype.toString ( [ radix ] ) [2] 7.1.12ToString ( argument ) [3] 7.1.12.1 NumberToString ( m )

EDIT: References