Stage 1 Draft / July 15, 2025

Keep trailing zeros in Intl.NumberFormat and Intl.PluralRules

16 NumberFormat Objects

16.5 Abstract Operations for NumberFormat Objects

16.5.3 FormatNumericToString ( intlObject, x, stringDigits )

The abstract operation FormatNumericToString takes arguments intlObject (an Object), x (a mathematical value or negative-zero), and stringDigits (an integer) and returns a Record with fields [[RoundedNumber]] (a mathematical value or negative-zero) and [[FormattedString]] (a String). It rounds x to an Intl mathematical value according to the internal slots of intlObject. The [[RoundedNumber]] field contains the rounded result value and the [[FormattedString]] field contains a String value representation of that result formatted according to the internal slots of intlObject. It performs the following steps when called:

  1. Assert: intlObject has [[RoundingMode]], [[RoundingType]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[RoundingIncrement]], and [[TrailingZeroDisplay]] internal slots.
  2. If x is negative-zero, then
    1. Let sign be negative.
    2. Set x to 0.
  3. Else,
    1. Assert: x is a mathematical value.
    2. If x < 0, let sign be negative; else let sign be positive.
    3. If sign is negative, then
      1. Set x to -x.
  4. Let unsignedRoundingMode be GetUnsignedRoundingMode(intlObject.[[RoundingMode]], sign).
  5. If intlObject.[[RoundingType]] is significant-digits, then
    1. Let result be ToRawPrecision(x, stringDigits, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]], unsignedRoundingMode).
  6. Else if intlObject.[[RoundingType]] is fraction-digits, then
    1. Let result be ToRawFixed(x, stringDigits, intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]], intlObject.[[RoundingIncrement]], unsignedRoundingMode).
  7. Else,
    1. Let sResult be ToRawPrecision(x, stringDigits, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]], unsignedRoundingMode).
    2. Let fResult be ToRawFixed(x, stringDigits, intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]], intlObject.[[RoundingIncrement]], unsignedRoundingMode).
    3. If fResult.[[RoundingMagnitude]] < sResult.[[RoundingMagnitude]], let fixedIsMorePrecise be true; else let fixedIsMorePrecise be false.
    4. If intlObject.[[RoundingType]] is more-precision and fixedIsMorePrecise is true, then
      1. Let result be fResult.
    5. Else if intlObject.[[RoundingType]] is less-precision and fixedIsMorePrecise is false, then
      1. Let result be fResult.
    6. Else,
      1. Let result be sResult.
  8. Set x to result.[[RoundedNumber]].
  9. Let string be result.[[FormattedString]].
  10. If intlObject.[[TrailingZeroDisplay]] is "stripIfInteger" and x modulo 1 = 0, then
    1. Let i be StringIndexOf(string, ".", 0).
    2. If i is not not-found, set string to the substring of string from 0 to i.
  11. Let int be result.[[IntegerDigitsCount]].
  12. Let minInteger be intlObject.[[MinimumIntegerDigits]].
  13. If int < minInteger, then
    1. Let forwardZeros be the String consisting of minInteger - int occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Set string to the string-concatenation of forwardZeros and string.
  14. If sign is negative, then
    1. If x is 0, set x to negative-zero. Otherwise, set x to -x.
  15. Return the Record { [[RoundedNumber]]: x, [[FormattedString]]: string }.

16.5.4 PartitionNumberPattern ( numberFormat, x )

The abstract operation PartitionNumberPattern takes arguments numberFormat (an object initialized as a NumberFormat) and x (a mathematical value or an Intl mathematical value) and returns a List of Records with fields [[Type]] (a String) and [[Value]] (a String). It creates the parts representing the mathematical value of xintlMV according to the effective locale and the formatting options of numberFormat. It performs the following steps when called:

  1. If x is an Intl mathematical value, then
    1. Let stringDigits be x.[[StringDigits]].
    2. Set x to x.[[Value]].
  2. Else,
    1. Assert: x is a mathematical value.
    2. Let stringDigits be 0.
  3. Let exponent be 0.
  4. If x is not-a-number, then
    1. Let n be an ILD String value indicating the NaN value.
  5. Else if x is positive-infinity, then
    1. Let n be an ILD String value indicating positive infinity.
  6. Else if x is negative-infinity, then
    1. Let n be an ILD String value indicating negative infinity.
  7. Else,
    1. If x is not negative-zero, then
      1. Assert: x is a mathematical value.
      2. If numberFormat.[[Style]] is "percent", set x be 100 × x.
      3. Set exponent to ComputeExponent(numberFormat, x).
      4. Set x to x × 10-exponent.
    2. Let formatNumberResult be FormatNumericToString(numberFormat, x, stringDigits).
    3. Let n be formatNumberResult.[[FormattedString]].
    4. Set x to formatNumberResult.[[RoundedNumber]].
  8. Let pattern be GetNumberFormatPattern(numberFormat, x).
  9. Let result be a new empty List.
  10. Let patternParts be PartitionPattern(pattern).
  11. For each Record { [[Type]], [[Value]] } patternPart of patternParts, do
    1. Let p be patternPart.[[Type]].
    2. If p is "literal", then
      1. Append the Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } to result.
    3. Else if p is "number", then
      1. If x is not-a-number, then
        1. Append the Record { [[Type]]: "nan", [[Value]]: n } to result.
      2. Else if x is positive-infinity or negative-infinity, then
        1. Append the Record { [[Type]]: "infinity", [[Value]]: n } to result.
      3. Else,
        1. Let notationSubParts be PartitionNotationSubPattern(numberFormat, x, n, exponent).
        2. Set result to the list-concatenation of result and notationSubParts.
    4. Else if p is "plusSign", then
      1. Let plusSignSymbol be the ILND String representing the plus sign.
      2. Append the Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } to result.
    5. Else if p is "minusSign", then
      1. Let minusSignSymbol be the ILND String representing the minus sign.
      2. Append the Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } to result.
    6. Else if p is "percentSign" and numberFormat.[[Style]] is "percent", then
      1. Let percentSignSymbol be the ILND String representing the percent sign.
      2. Append the Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } to result.
    7. Else if p is "unitPrefix" and numberFormat.[[Style]] is "unit", then
      1. Let unit be numberFormat.[[Unit]].
      2. Let unitDisplay be numberFormat.[[UnitDisplay]].
      3. Let mu be an ILD String value representing unit before x in unitDisplay form, which may depend on x in languages having different plural forms.
      4. Append the Record { [[Type]]: "unit", [[Value]]: mu } to result.
    8. Else if p is "unitSuffix" and numberFormat.[[Style]] is "unit", then
      1. Let unit be numberFormat.[[Unit]].
      2. Let unitDisplay be numberFormat.[[UnitDisplay]].
      3. Let mu be an ILD String value representing unit after x in unitDisplay form, which may depend on x in languages having different plural forms.
      4. Append the Record { [[Type]]: "unit", [[Value]]: mu } to result.
    9. Else if p is "currencyCode" and numberFormat.[[Style]] is "currency", then
      1. Let currency be numberFormat.[[Currency]].
      2. Let cd be currency.
      3. Append the Record { [[Type]]: "currency", [[Value]]: cd } to result.
    10. Else if p is "currencyPrefix" and numberFormat.[[Style]] is "currency", then
      1. Let currency be numberFormat.[[Currency]].
      2. Let currencyDisplay be numberFormat.[[CurrencyDisplay]].
      3. Let cd be an ILD String value representing currency before x in currencyDisplay form, which may depend on x in languages having different plural forms.
      4. Append the Record { [[Type]]: "currency", [[Value]]: cd } to result.
    11. Else if p is "currencySuffix" and numberFormat.[[Style]] is "currency", then
      1. Let currency be numberFormat.[[Currency]].
      2. Let currencyDisplay be numberFormat.[[CurrencyDisplay]].
      3. Let cd be an ILD String value representing currency after x in currencyDisplay form, which may depend on x in languages having different plural forms. If the implementation does not have such a representation of currency, use currency itself.
      4. Append the Record { [[Type]]: "currency", [[Value]]: cd } to result.
    12. Else,
      1. Let unknown be an ILND String based on x and p.
      2. Append the Record { [[Type]]: "unknown", [[Value]]: unknown } to result.
  12. Return result.

16.5.5 PartitionNotationSubPattern ( numberFormat, x, n, exponent )

The abstract operation PartitionNotationSubPattern takes arguments numberFormat (an Intl.NumberFormat), x (an Intla mathematical value, or negative-zero.), n (a String), and exponent (an integer) and returns a List of Records with fields [[Type]] (a String) and [[Value]] (a String). x is an Intla mathematical value after rounding is applied and n is an intermediate formatted string. It creates the corresponding parts for the number and notation according to the effective locale and the formatting options of numberFormat. It performs the following steps when called:

  1. Let result be a new empty List.
  2. If x is not-a-number, then
    1. Append the Record { [[Type]]: "nan", [[Value]]: n } to result.
  3. Else if x is positive-infinity or negative-infinity, then
    1. Append the Record { [[Type]]: "infinity", [[Value]]: n } to result.
  4. Else,
  5. Let notationSubPattern be GetNotationSubPattern(numberFormat, exponent).
  6. Let patternParts be PartitionPattern(notationSubPattern).
  7. For each Record { [[Type]], [[Value]] } patternPart of patternParts, do
    1. Let p be patternPart.[[Type]].
    2. If p is "literal", then
      1. Append the Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } to result.
    3. Else if p is "number", then
      1. ...
    4. Else if p is "compactSymbol", then
      1. ...
    5. Else if p is "compactName", then
      1. ...
    6. Else if p is "scientificSeparator", then
      1. ...
    7. Else if p is "scientificExponent", then
      1. If exponent < 0, then
        1. Let minusSignSymbol be the ILND String representing the minus sign.
        2. Append the Record { [[Type]]: "exponentMinusSign", [[Value]]: minusSignSymbol } to result.
        3. Let exponent be -exponent.
      2. Let exponentResult be ToRawFixed(exponent, 0, 0, 0, 1, undefined).
      3. Append the Record { [[Type]]: "exponentInteger", [[Value]]: exponentResult.[[FormattedString]] } to result.
    8. Else,
      1. Let unknown be an ILND String based on x and p.
      2. Append the Record { [[Type]]: "unknown", [[Value]]: unknown } to result.
  8. Return result.

16.5.6 FormatNumeric ( numberFormat, x )

The abstract operation FormatNumeric takes arguments numberFormat (an Intl.NumberFormat) and x (a mathematical value or an Intl mathematical value) and returns a String. It performs the following steps when called:

  1. Let parts be PartitionNumberPattern(numberFormat, x).
  2. Let result be the empty String.
  3. For each Record { [[Type]], [[Value]] } part of parts, do
    1. Set result to the string-concatenation of result and part.[[Value]].
  4. Return result.

16.5.8 ToRawPrecision ( x, stringDigits, minPrecision, maxPrecision, unsignedRoundingMode )

The abstract operation ToRawPrecision takes arguments x (a non-negative mathematical value), stringDigits (an integer), minPrecision (an integer in the inclusive interval from 1 to 21), maxPrecision (an integer in the inclusive interval from 1 to 21), and unsignedRoundingMode (a specification type from the Unsigned Rounding Mode column of Table 29, or undefined) and returns a Record with fields [[FormattedString]] (a String), [[RoundedNumber]] (a mathematical value), [[IntegerDigitsCount]] (an integer), and [[RoundingMagnitude]] (an integer).

It involves solving the following equation, which returns a valid mathematical value given integer inputs:

ToRawPrecisionFn(n, e, p) = n × 10ep+1
where 10p–1n < 10p

It performs the following steps when called:

  1. Let p be maxPrecision.
  2. If x = 0, then
    1. Let m be the String consisting of p occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Let e be 0.
    3. Let xFinal be 0.
  3. Else,
    1. Let n1 and e1 each be an integer and r1 a mathematical value, with r1 = ToRawPrecisionFn(n1, e1, p), such that r1x and r1 is maximized.
    2. Let n2 and e2 each be an integer and r2 a mathematical value, with r2 = ToRawPrecisionFn(n2, e2, p), such that r2x and r2 is minimized.
    3. Let xFinal be ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode).
    4. If xFinal is r1, then
      1. Let n be n1.
      2. Let e be e1.
    5. Else,
      1. Let n be n2.
      2. Let e be e2.
    6. Let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
  4. If e ≥ (p - 1), then
    1. Set m to the string-concatenation of m and e - p + 1 occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Let int be e + 1.
  5. Else if e ≥ 0, then
    1. Set m to the string-concatenation of the first e + 1 code units of m, the code unit 0x002E (FULL STOP), and the remaining p - (e + 1) code units of m.
    2. Let int be e + 1.
  6. Else,
    1. Assert: e < 0.
    2. Set m to the string-concatenation of "0.", -(e + 1) occurrences of the code unit 0x0030 (DIGIT ZERO), and m.
    3. Let int be 1.
  7. If m contains the code unit 0x002E (FULL STOP) and maxPrecision > minPrecision, then
    1. Let cut be maxPrecision - minPrecisionmax(stringDigits, minPrecision).
    2. Repeat, while cut > 0 and the last code unit of m is 0x0030 (DIGIT ZERO),
      1. Remove the last code unit from m.
      2. Set cut to cut - 1.
    3. If the last code unit of m is 0x002E (FULL STOP), then
      1. Remove the last code unit from m.
  8. Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: ep+1 }.

16.5.9 ToRawFixed ( x, stringDigits, minFraction, maxFraction, roundingIncrement, unsignedRoundingMode )

The abstract operation ToRawFixed takes arguments x (a non-negative mathematical value), stringDigits (an integer), minFraction (an integer in the inclusive interval from 0 to 100), maxFraction (an integer in the inclusive interval from 0 to 100), roundingIncrement (an integer), and unsignedRoundingMode (a specification type from the Unsigned Rounding Mode column of Table 29, or undefined) and returns a Record with fields [[FormattedString]] (a String), [[RoundedNumber]] (a mathematical value), [[IntegerDigitsCount]] (an integer), and [[RoundingMagnitude]] (an integer).

It involves solving the following equation, which returns a valid mathematical value given integer inputs:

ToRawFixedFn(n, f) = n × 10f

It performs the following steps when called:

  1. Let f be maxFraction.
  2. Let n1 be an integer and r1 a mathematical value, with r1 = ToRawFixedFn(n1, f), such that n1 modulo roundingIncrement = 0, r1x, and r1 is maximized.
  3. Let n2 be an integer and r2 a mathematical value, with r2 = ToRawFixedFn(n2, f), such that n2 modulo roundingIncrement = 0, r2x, and r2 is minimized.
  4. Let xFinal be ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode).
  5. If xFinal is r1, let n be n1. Otherwise, let n be n2.
  6. If n = 0, let m be "0". Otherwise, let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
  7. If f ≠ 0, then
    1. Let k be the length of m.
    2. If kf, then
      1. Let z be the String value consisting of f + 1 - k occurrences of the code unit 0x0030 (DIGIT ZERO).
      2. Set m to the string-concatenation of z and m.
      3. Set k to f + 1.
    3. Let a be the first k - f code units of m, and let b be the remaining f code units of m.
    4. Set m to the string-concatenation of a, ".", and b.
    5. Let int be the length of a.
    6. Let cut be maxFraction - max(stringDigits - int, minFraction).
    7. Repeat, while cut > 0 and the last code unit of b is 0x0030 (DIGIT ZERO),
      1. Remove the last code unit from b.
      2. Set cut to cut - 1.
    8. If b is the empty String, set m to a.
    9. Else, set m to the string-concatenation of a, ".", and b.
  8. Else,
    1. Let int be the length of m.
  9. Let cut be maxFraction - minFraction.
  10. Repeat, while cut > 0 and the last code unit of m is 0x0030 (DIGIT ZERO),
    1. Remove the last code unit from m.
    2. Set cut to cut - 1.
  11. If the last code unit of m is 0x002E (FULL STOP), then
    1. Remove the last code unit from m.
  12. Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: –f }.

16.5.11 GetNumberFormatPattern ( numberFormat, x )

The abstract operation GetNumberFormatPattern takes arguments numberFormat (an Intl.NumberFormat) and x (an Intl mathematical valueeither a mathematical value or one of positive-infinity, negative-infinity, not-a-number, or negative-zero) and returns a String. It considers the resolved unit-related options in the number format object along with the final scaled and rounded number being formatted(an Intl mathematical value) and returns a pattern, a String value as described in 16.2.3. It performs the following steps when called:

  1. ...

16.5.13 ComputeExponent ( numberFormat, x )

The abstract operation ComputeExponent takes arguments numberFormat (an Intl.NumberFormat) and x (a mathematical value) and returns an integer. It computes an exponent (power of ten) by which to scale x according to the number formatting settings. It handles cases such as 999 rounding up to 1000, requiring a different exponent. It performs the following steps when called:

  1. If x = 0, then
    1. Return 0.
  2. If x < 0, then
    1. Let x = -x.
  3. Let magnitude be the base 10 logarithm of x rounded down to the nearest integer.
  4. Let exponent be ComputeExponentForMagnitude(numberFormat, magnitude).
  5. Let x be x × 10-exponent.
  6. Let formatNumberResult be FormatNumericToString(numberFormat, x, 0).
  7. If formatNumberResult.[[RoundedNumber]] = 0, then
    1. Return exponent.
  8. Let newMagnitude be the base 10 logarithm of formatNumberResult.[[RoundedNumber]] rounded down to the nearest integer.
  9. If newMagnitude is magnitude - exponent, then
    1. Return exponent.
  10. Return ComputeExponentForMagnitude(numberFormat, magnitude + 1).

16.5.15 Runtime Semantics: StringIntlMV

The syntax-directed operation StringIntlMV takes no arguments.

Note

The conversion of a StringNumericLiteral to a Number value is similar overall to the determination of the NumericValue of a NumericLiteral (see 12.9.3), but some of the details are different.

The conversion of a StringNumericLiteral to a mathematical value and a precision is similar overall to the determination of the NumericValue of a NumericLiteral (see 12.9.3), but some of the details are different. The result of StringIntlMV is a List value with two elements, a mathematical value and the number of decimal digits in the source text.

It is defined piecewise over the following productions:

StringNumericLiteral ::: StrWhiteSpaceopt
  1. Return 0« 0, 0 ».
StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
  1. Return StringIntlMV of StrNumericLiteral.
StrNumericLiteral ::: NonDecimalIntegerLiteral
  1. Return MV of NonDecimalIntegerLiteral.
  2. Let i be MV of NonDecimalIntegerLiteral.
  3. Return « i, 0 ».
StrDecimalLiteral ::: - StrUnsignedDecimalLiteral
  1. Let ax be StringIntlMV of StrUnsignedDecimalLiteral.
  2. Let a be the first element of x.
  3. Let n be the second element of x.
  4. If a is 0, return negative-zero« negative-zero, n ».
  5. If a is positive-infinity, return negative-infinity« negative-infinity, 0 ».
  6. Return -a« -a, n ».
StrUnsignedDecimalLiteral ::: Infinity
  1. Return positive-infinity« positive-infinity, 0 ».
StrUnsignedDecimalLiteral ::: DecimalDigits . DecimalDigitsopt ExponentPartopt
  1. Let a be MV of the first DecimalDigits.
  2. Let m be the number of code points in the first DecimalDigits.
  3. If the second DecimalDigits is present, then
    1. Let b be MV of the second DecimalDigits.
    2. Let n be the number of code points in the second DecimalDigits.
  4. Else,
    1. Let b be 0.
    2. Let n be 0.
  5. If ExponentPart is present, let e be MV of ExponentPart. Otherwise, let e be 0.
  6. Return « (a + (b × 10-n)) × 10e, m + n ».
StrUnsignedDecimalLiteral ::: . DecimalDigits ExponentPartopt
  1. Let b be MV of DecimalDigits.
  2. If ExponentPart is present, let e be MV of ExponentPart. Otherwise, let e be 0.
  3. Let n be the number of code points in DecimalDigits.
  4. Return « b × 10e - n, n ».
StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPartopt
  1. Let a be MV of DecimalDigits.
  2. Let m be the number of code points in DecimalDigits.
  3. If ExponentPart is present, let e be MV of ExponentPart. Otherwise, let e be 0.
  4. Return « a × 10e, m ».

16.5.16 ToIntlMathematicalValue ( value )

The abstract operation ToIntlMathematicalValue takes argument value (an ECMAScript language value) and returns either a normal completion containing an Intl mathematical value or a throw completion. It returns value converted to an Intl mathematical value, whicha Record with two fields: [[Value]] is a mathematical value together withor one of positive-infinity, negative-infinity, not-a-number, or negative-zero, and negative-zero[[StringDigits]] is an integer indicating the number of significant digits in value when it is a String, or 0 otherwise. This abstract operation is similar to 7.1.3, but a mathematical value can be returned instead of a Number or BigInt, so that and the full precision of the parsed string is retained, allowing exact decimal values canto be represented. It performs the following steps when called:

  1. Let primValue be ? ToPrimitive(value, number).
  2. If primValue is a BigInt, return (primValue)the Record { [[Value]]: (primValue), [[StringDigits]]: 0 }.
  3. If primValue is a String, then
    1. Let str be primValue.
    2. Let text be StringToCodePoints(primValue).
    3. Let literal be ParseText(text, StringNumericLiteral).
    4. If literal is a List of errors, return the Record { [[Value]]: not-a-number, [[StringDigits]]: 0 }.
    5. Let parseRes be the StringIntlMV of literal.
    6. Let x be the first element of parseRes.
    7. Let stringDigits be the second element of parseRes.
    8. If x is a mathematical value, then
      1. Let rounded be RoundMVResult(abs(x)).
      2. If rounded is +∞𝔽, then
        1. If x < 0, set x to negative-infinity.
        2. Else, set x to positive-infinity.
        3. Set stringDigits to 0.
      3. If rounded is +0𝔽 and x < 0, set x to negative-zero.
    9. Return the Record { [[Value]]: x, [[StringDigits]]: stringDigits }.
  4. Else,
    1. Let x be ? ToNumber(primValue).
    2. If x is -0𝔽, return negative-zero.
    3. Let str be Number::toString(x, 10).
    4. Let n be ? ToNumber(primValue).
    5. If n is NaN, let x be not-a-number.
    6. Else if n is +∞𝔽, let x be positive-infinity.
    7. Else if n is -∞𝔽, let x be negative-infinity.
    8. Else, let x be (n).
    9. Return the Record { [[Value]]: x, [[StringDigits]]: 0 }.
  5. Let text be StringToCodePoints(str).
  6. Let literal be ParseText(text, StringNumericLiteral).
  7. If literal is a List of errors, return not-a-number.
  8. Let intlMV be the StringIntlMV of literal.
  9. If intlMV is a mathematical value, then
    1. Let rounded be RoundMVResult(abs(intlMV)).
    2. If rounded is +∞𝔽 and intlMV < 0, return negative-infinity.
    3. If rounded is +∞𝔽, return positive-infinity.
    4. If rounded is +0𝔽 and intlMV < 0, return negative-zero.
    5. If rounded is +0𝔽, return 0.
  10. Return intlMV.

16.5.17 PartitionNumberRangePattern ( numberFormat, x, y )

The abstract operation PartitionNumberRangePattern takes arguments numberFormat (an Intl.NumberFormat), x (an Intl mathematical value), and y (an Intl mathematical value) and returns either a normal completion containing a List of Records with fields [[Type]] (a String), [[Value]] (a String), and [[Source]] (a String), or a throw completion. It creates the parts for a localized number range according to x, y, and the formatting options of numberFormat. It performs the following steps when called:

  1. If x.[[Value]] is not-a-number or y.[[Value]] is not-a-number, throw a RangeError exception.
  2. Let xResult be PartitionNumberPattern(numberFormat, x).
  3. Let yResult be PartitionNumberPattern(numberFormat, y).
  4. If FormatNumeric(numberFormat, x) is FormatNumeric(numberFormat, y), then
    1. Let appxResult be FormatApproximately(numberFormat, xResult).
    2. For each element r of appxResult, do
      1. Set r.[[Source]] to "shared".
    3. Return appxResult.
  5. Let result be a new empty List.
  6. For each element r of xResult, do
    1. Append the Record { [[Type]]: r.[[Type]], [[Value]]: r.[[Value]], [[Source]]: "startRange" } to result.
  7. Let rangeSeparator be an ILND String value used to separate two numbers.
  8. Append the Record { [[Type]]: "literal", [[Value]]: rangeSeparator, [[Source]]: "shared" } to result.
  9. For each element r of yResult, do
    1. Append the Record { [[Type]]: r.[[Type]], [[Value]]: r.[[Value]], [[Source]]: "endRange" } to result.
  10. Return CollapseNumberRange(numberFormat, result).

17 PluralRules Objects

17.3 Properties of the Intl.PluralRules Prototype Object

17.3.3 Intl.PluralRules.prototype.select ( value )

When the select method is called with an argument value, the following steps are taken:

  1. Let pr be the this value.
  2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
  3. Let nintlMV be ? ToNumber(value)ToIntlMathematicalValue(value).
  4. Return ResolvePlural(pr, n).[[PluralCategory]].intlMV).[[PluralCategory]].

17.3.4 Intl.PluralRules.prototype.selectRange ( start, end )

When the selectRange method is called with arguments start and end, the following steps are taken:

  1. Let pr be the this value.
  2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
  3. If start is undefined or end is undefined, throw a TypeError exception.
  4. Let x be ? ToNumber(start)ToIntlMathematicalValue(start).
  5. Let y be ? ToNumber(end)ToIntlMathematicalValue(end).
  6. Return ? ResolvePluralRange(pr, x, y).

17.5 Abstract Operations for PluralRules Objects

17.5.2 ResolvePlural ( pluralRules, n, intlMV )

The abstract operation ResolvePlural takes arguments pluralRules (an Intl.PluralRules), n (a Number), and intlMV (an Intl mathematical value) and returns a Record with fields [[PluralCategory]] ("zero", "one", "two", "few", "many", or "other") and [[FormattedString]] (a String). The returned Record contains two string-valued fields describing nintlMV according to the effective locale and the options of pluralRules: [[PluralCategory]] characterizing its plural category, and [[FormattedString]] containing its formatted representation. It performs the following steps when called:

  1. If n is not a finite Number, then
    1. Let s be ! ToString(n)
    2. Return the Record { [[PluralCategory]]: "other", [[FormattedString]]: s }.
  2. Let x be intlMV.[[Value]].
  3. Let stringDigits be intlMV.[[StringDigits]].
  4. If x is not-a-number, then
    1. Return the Record { [[PluralCategory]]: "other", [[FormattedString]]: "NaN" }.
  5. Else if x is positive-infinity, then
    1. Return the Record { [[PluralCategory]]: "other", [[FormattedString]]: "Infinity" }.
  6. Else if x is negative-infinity, then
    1. Return the Record { [[PluralCategory]]: "other", [[FormattedString]]: "-Infinity" }.
  7. Let res be FormatNumericToString(pluralRules, (n)x, stringDigits).
  8. Let s be res.[[FormattedString]].
  9. Let locale be pluralRules.[[Locale]].
  10. Let type be pluralRules.[[Type]].
  11. Let notation be pluralRules.[[Notation]].
  12. Let p be PluralRuleSelect(locale, type, notation, s).
  13. Return the Record { [[PluralCategory]]: p, [[FormattedString]]: s }.

17.5.4 ResolvePluralRange ( pluralRules, x, y )

The abstract operation ResolvePluralRange takes arguments pluralRules (an Intl.PluralRules), x (a Numberan Intl mathematical value), and y (a Numberan Intl mathematical value) and returns either a normal completion containing either "zero", "one", "two", "few", "many", or "other", or a throw completion. The returned String value represents the plural form of the range starting from x and ending at y according to the effective locale and the options of pluralRules. It performs the following steps when called:

  1. If x.[[Value]] is NaNnot-a-number or y.[[Value]] is NaNnot-a-number, throw a RangeError exception.
  2. Let xp be ResolvePlural(pluralRules, x).
  3. Let yp be ResolvePlural(pluralRules, y).
  4. If xp.[[FormattedString]] is yp.[[FormattedString]], then
    1. Return xp.[[PluralCategory]].
  5. Let locale be pluralRules.[[Locale]].
  6. Let type be pluralRules.[[Type]].
  7. Let notation be pluralRules.[[Notation]].
  8. Return PluralRuleSelectRange(locale, type, notation, xp.[[PluralCategory]], yp.[[PluralCategory]]).

Copyright & Software License

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.