tc39 / ecma402

Status, process, and documents for ECMA 402
https://tc39.es/ecma402/
Other
539 stars 107 forks source link

Provide a method for formatting numbers not represented by Number #334

Open rakudrama opened 5 years ago

rakudrama commented 5 years ago

It is fairly common for applications to handle numeric data that cannot be represented as a JavaScript number.

In the case of BigInt and extended precision libraries, the bounds on the allowable formatting parameters don't make much sense. A BigInt could have 100 digits, but should still be formatted with the localized digit grouping. An extended floating-point library should not be limited to 21 significant digits.

I'd like to see NumberFormat be capable of formatting these inputs. It is reasonable to expect these inputs to provide an API for digit generation, but Intl should handle everything that is localized.

As it currently stands applications contain an approximation to Intl.NumberFormat written in (or compiled to) JavaScript. The quality of the approximation varies, but the good ones are quite expensive, with measurable application startup latency due to effectively cloning part of ICU in the JavaScript code.

littledan commented 5 years ago

For BigInt, see a proposal in https://github.com/tc39/ecma402/pull/236 . For your decimal use cases, well, I'd like to add a Decimal datatype to JavaScript. I hope it won't take too long! Let's consider adding ECMA-402 features which don't need to reference the Decimal data type if it seems unlikely to be standardized in the future.

rakudrama commented 5 years ago

@littledan The main issue for my customers is MicroMoney. While I would welcome a Decimal type, the 'enormous' apps in question are so large as to be 'locked in' to the current types. We could use NumberFormat on Decimal only if there was a reasonably efficient conversion from the current representation to the Decimal type.

A useful option would be a scale, indicating the value is already scaled by 10^scale, for both positive and negative values. (I'm not sure if scale should be an option or an argument to format.) If I could format a BigInt with scale: 6 then it would solve the first bullet point. There is already scaling implicit in '%', albeit in the other direction (-2). scale could also be used for fixing a mismatch with units in the format (the application stores a weight in Kg and wants 0.05 displayed as 50 g without doing division itself).

littledan commented 5 years ago

@rakudrama Thanks for explaining your use case. I think there should be a reasonably efficient operation to create a Decimal value of the kind you need here, if we create a Decimal type.

sffc commented 4 years ago

407 was a duplicate issue filed for this feature.

@littledan Do you think it is wise to move forward with a { scale } option to Intl.NumberFormat, which, combined with BigInt, can allow the formatting of arbitrary precision numbers, or is it better to wait for the Decimal proposal?

sffc commented 4 years ago

Okay. From a discussion with @littledan, my understanding is that there are basically three options; we could do one, two, or all three:

  1. Allow strings to be interpreted as decimal numbers. May or may not be web-compatible. Requires reifying the syntax for decimal number strings.
    • Q: Do we allow grouping separators in decimal number syntax? Probably not.
      const nf = new Intl.NumberFormat("en-US");
      nf.format("1.23E4");  // => "12,300"
  2. Add a { scale } option to multiply the input number by a power of 10. We already do this when style="percent".
    • Note: covers use case where you already have a BigInt representing currency micros. You can easily format the BigInt using { scale: -6 }.
      const nf = new Intl.NumberFormat("en-US", { scale: -3 });
      nf.format(1230n);  // ==> "1.23"
  3. Wait for the Decimal proposal for formatting things not supported by Number or BigInt.
sffc commented 4 years ago

I plan to address this as part of my new proposal Intl.NumberFormat V3.

https://github.com/sffc/proposal-intl-numberformat-v3

littledan commented 4 years ago

The current status is, we're working towards allowing strings to be interpreted as decimal numbers, but holding off on the scale option, due to the difficulty in finding a good solution to https://github.com/tc39/proposal-intl-numberformat-v3/issues/1 .

Yaffle commented 3 years ago

@sffc , hi thanks for working on this! Is there plans to increase the limit for maximumFractionDigits (to allow more than 20) ? Of course, we can format only integer strings, but may be someone needs it.

sffc commented 3 years ago

@sffc , hi thanks for working on this! Is there plans to increase the limit for maximumFractionDigits (to allow more than 20) ? Of course, we can format only integer strings, but may be someone needs it.

Good question; can you open an issue on https://github.com/sffc/proposal-intl-numberformat-v3?

Yaffle commented 3 years ago

@sffc, https://github.com/tc39/proposal-intl-numberformat-v3/issues/34