From 8124e2e618203e64b42e73bbb7bf49e65a0d3877 Mon Sep 17 00:00:00 2001 From: Michael Dyck Date: Wed, 2 Dec 2020 17:27:11 -0500 Subject: [PATCH] Editorial: Define + use StringToNumber Formerly, the procedure for applying ToNumber to the String type was spread over three widely-separated prose paragraphs in two different clauses. This commit brings all that together, expresses it as an actual algorithm, and gives it the name StringToNumber. Also, the definitions of the syntax-direction operation NumericValue mostly just delegated to a prose description. This commit replaces that with actual algorithms, similar to that for StringToNumber. --- spec.html | 52 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/spec.html b/spec.html index 55bcc4ae4a5..96acf7b2988 100644 --- a/spec.html +++ b/spec.html @@ -4277,7 +4277,7 @@

ToNumber ( _argument_ )

String - See grammar and conversion algorithm below. + Return ! StringToNumber(_argument_). @@ -4314,7 +4314,7 @@

ToNumber ( _argument_ )

ToNumber Applied to the String Type

-

ToNumber applied to Strings applies the following grammar to the input String interpreted as a sequence of UTF-16 encoded code points (). If the grammar cannot interpret the String as an expansion of |StringNumericLiteral|, then the result of ToNumber is *NaN*.

+

The abstract operation StringToNumber specifies how to convert a String value to a Number value. Overall, the process is similar to the determination of the NumericValue of a numeric literal (see ), but some of the details are different.

Syntax

StringNumericLiteral ::: @@ -4370,7 +4370,6 @@

Syntax

Runtime Semantics: MV

-

The conversion of a String to a Number value is similar overall to the determination of the Number value for a numeric literal (see ), but some of the details are different, so the process for converting a String numeric literal to a value of Number type is given here. This value is determined in two steps: first, a mathematical value (MV) is derived from the String numeric literal; second, this mathematical value is rounded as described below. The MV on any grammar symbol, not provided below, is the MV for that symbol defined in .

  • The MV of StringNumericLiteral ::: [empty] is 0. @@ -4406,7 +4405,29 @@

    Runtime Semantics: MV

    The MV of StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPart is the MV of |DecimalDigits| times 10_e_, where _e_ is the MV of |ExponentPart|.
-

Once the exact MV for a String numeric literal has been determined, it is then rounded to a value of the Number type. If the MV is 0, then the rounded value is *+0*𝔽 unless the first non white space code point in the String numeric literal is `-`, in which case the rounded value is *-0*𝔽. Otherwise, the rounded value must be the Number value for the MV (in the sense defined in ), unless the literal includes a |StrUnsignedDecimalLiteral| and the literal has more than 20 significant digits, in which case the Number value may be either the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a 0 digit or the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a 0 digit and then incrementing the literal at the 20th digit position. A digit is significant if it is not part of an |ExponentPart| and

+

For the MV of any production not shown above, see .

+
+ + +

StringToNumber ( _str_ )

+

The abstract operation StringToNumber takes argument _str_ (a String) and returns a Number. It performs the following steps when called:

+ + 1. Let _text_ be ! StringToCodePoints(_str_). + 1. Let _literal_ be ParseText(_text_, |StringNumericLiteral|). + 1. If _literal_ is a List of errors, return *NaN*. + 1. If _literal_ contains a |StrUnsignedDecimalLiteral| and _literal_ has more than 20 significant digits, then + 1. Let _lit_ be an implementation-defined choice of: + * _literal_ + * a literal produced from _literal_ by replacing each significant digit after the 20th with a `0` digit + * a literal produced from _literal_ by replacing each significant digit after the 20th with a `0` digit and then incrementing the literal at the 20th significant digit position + 1. Else, + 1. Let _lit_ be _literal_. + 1. Let _mv_ be the MV of _lit_. + 1. If _mv_ is 0 and the first non white space code point in _text_ is `-`, return *-0*𝔽. + 1. Return 𝔽(_mv_). + + +

A digit is significant if it is not part of an |ExponentPart| and

  • it is not `0`; or @@ -11027,7 +11048,7 @@

    Syntax

    Static Semantics: MV

    -

    A numeric literal stands for a value of the Number type or the BigInt type.

    +

    A numeric literal stands for a value of the Number type or the BigInt type, as specified by the syntax-directed operation NumericValue. Determining this value involves deriving a mathematical value (MV) from the literal, according to the following rules.

    • The MV of NumericLiteral :: DecimalLiteral is the MV of |DecimalLiteral|. @@ -11193,15 +11214,26 @@

      Static Semantics: MV

      Static Semantics: NumericValue

      - NumericLiteral :: DecimalLiteral + NumericLiteral :: NonDecimalIntegerLiteral - 1. Return the Number value that results from rounding the MV of |DecimalLiteral| as described below. + 1. Let _mv_ be the MV of |NonDecimalIntegerLiteral|. + 1. Return 𝔽(_mv_). - NumericLiteral :: NonDecimalIntegerLiteral + + NumericLiteral :: DecimalLiteral - 1. Return the Number value that results from rounding the MV of |NonDecimalIntegerLiteral| as described below. + 1. If |DecimalLiteral| has more than 20 significant digits, then + 1. Let _lit_ be an implementation-defined choice of: + * |DecimalLiteral| + * a literal produced from |DecimalLiteral| by replacing each significant digit after the 20th with a `0` digit + * a literal produced from |DecimalLiteral| by replacing each significant digit after the 20th with a `0` digit and then incrementing the literal at the 20th significant digit position + 1. Else, + 1. Let _lit_ be |DecimalLiteral|. + 1. Let _mv_ be the MV of _lit_. + 1. Return 𝔽(_mv_). -

      Once the exact MV for a numeric literal has been determined, it is then rounded to a value of the Number type. If the MV is 0, then the rounded value is *+0*𝔽; otherwise, the rounded value must be the Number value for the MV (as specified in ), unless the literal is a |DecimalLiteral| and the literal has more than 20 significant digits, in which case the Number value may be either the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a `0` digit or the Number value for the MV of a literal produced by replacing each significant digit after the 20th with a `0` digit and then incrementing the literal at the 20th significant digit position. A digit is significant if it is not part of an |ExponentPart| and

      + +

      A digit is significant if it is not part of an |ExponentPart| and

      • it is not `0`; or