1 of 11

Intl Number Format V3

for Stage 4

Shane Carr

January 2023 TC39

2 of 11

What is this?

Dozens of feature requests get filed against ECMA-402 every year.

How do we decide which ones to prioritize?

  1. Multiple companies/stakeholders.
  2. Already has Unicode/CLDR algorithms we can cite.
  3. Not easily implemented in user land.

3 of 11

Decision Process Examples

Feature

Stakeholders

CLDR Support

Verdict

Google

Partial

No

Google, CaixaBank, Community

Yes

Yes

4 of 11

Proposal Changes

green text = changed since previous Stage 3 update in November 2022

5 of 11

Intl.NumberFormat formatRange: Overview

Main issue: #393

Use cases:

  • Number ranges
    • What versions of Android are supported?
  • Currency ranges
    • How much does a rideshare cost?
    • What's the expected payment on my mortgage?
  • Measurement unit ranges
    • What's the gas mileage of your car?

6 of 11

Rounding Priority (Details: #8)

Problem: what happens when you specify

{ maximumFractionDigits: 2, maximumSignificantDigits: 2 }

You specified two conflicting strategies [example: 4.321]:

  1. Round to the hundredths place (10^-2) [example: "4.32"]
  2. Round after the second significant digit [example: "4.3"]

New setting roundingPriority resolves this conflict:

  • "significantDigits" significant digits always win. [example: "4.3"] ⇒ current behavior
  • "morePrecision" the result with more precision wins. [example: "4.32"]
  • "lessPrecision" the result with less precision wins. [example: "4.3"]

7 of 11

Interpret Strings as Decimals

Main issue: #334

We already accept strings, but they get parsed as a Number, losing precision. This part of the proposal will interpret the decimal string at full precision.

How it works: a new type called Intl mathematical value: "a mathematical value together with +∞, -∞, NaN, and -0" [#82]. The range of an Intl mathematical value is equal to the range of a Number, but greater precision is allowed. [#128]

const nf = new Intl.NumberFormat("en-US");

const string = "987654321987654321";

nf.format(string);

// Current: "987,654,321,987,654,300"

// Proposed: "987,654,321,987,654,321"

8 of 11

Rounding Modes

Main issue: #419

We will adopt the following 9 rounding modes.

  • ceil (toward +∞)
  • floor (toward -∞)
  • expand (away from 0)
  • trunc (toward 0)

This set encompasses ICU, CSS, and ECMA-262 Math.

  • halfCeil (ties toward +∞)
  • halfFloor (ties toward -∞)
  • halfExpand (ties away from 0; current behavior; default)
  • halfTrunc (ties toward 0)
  • halfEven (ties toward the value with even cardinality)

9 of 11

Sign Display Negative

Main Issue: #17

We will add a new option signDisplay: "negative". The new option will behave like "auto" except that the sign will not be shown on negative zero.

var nf = new Intl.NumberFormat("en", {� signDisplay: "negative"�});�nf.format(-1.0); // -1�nf.format(-0.0); // 0 (note: "auto" produces "-0" here)�nf.format(0.0); // 0�nf.format(1.0); // 1 (note: "exceptZero" produces "+1" here)

10 of 11

Stage 4

11 of 11

Stage 4?

Entrance Criteria:

  • ✔️ Test262 Tests
    • See links in speaker notes
  • ✔️ Two compatible implementations which pass the acceptance tests
    • Chrome/V8 since m106
    • Safari/JSC since 15.4
    • Firefox/SM in nightly
  • ✔️ Significant in-the-field experience with shipping implementations
  • ✔️ A pull request has been sent
    • ecma402/pull/753
  • ⏳ All ECMAScript editors have signed off on the pull request
    • [Awaiting final review]