Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
rakudrama opened this issue Mar 15, 2019 · 10 comments
Open

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

rakudrama opened this issue Mar 15, 2019 · 10 comments
Assignees
Labels
c: numbers Component: numbers, currency, units s: in progress Status: the issue has an active proposal Small Smaller change solvable in a Pull Request

Comments

@rakudrama
Copy link

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

  • One enormous application uses 64-bit integers (represented by a triple of Smi values) with an implicit 6 decimal digit scaling, aka 'MicroMoney'. It is necessary to format these values without intermediate rounding or truncation from conversion to Number.

  • It should be possible to format the recently added JavaScript BigInt type with a NumberFormat. Note that BigInt by design provides no conversion to Number to prevent accidental truncation. ToNumber conversions throw.

  • There are numerous libraries for monetary or 'decimal' values that could benefit from consistent formatting.

  • There are extended precision libraries that could benefit from consistent formatting.

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
Copy link
Member

For BigInt, see a proposal in #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
Copy link
Author

@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
Copy link
Member

@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 sffc added c: numbers Component: numbers, currency, units s: help wanted Status: help wanted; needs proposal champion Small Smaller change solvable in a Pull Request labels Mar 19, 2019
@sffc
Copy link
Contributor

sffc commented Mar 20, 2020

#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 sffc added s: discuss Status: TG2 must discuss to move forward and removed s: help wanted Status: help wanted; needs proposal champion labels Mar 20, 2020
@sffc
Copy link
Contributor

sffc commented Mar 21, 2020

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"
  1. 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"
  1. Wait for the Decimal proposal for formatting things not supported by Number or BigInt.

@sffc
Copy link
Contributor

sffc commented Mar 21, 2020

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

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

@sffc sffc added s: in progress Status: the issue has an active proposal and removed s: discuss Status: TG2 must discuss to move forward labels Mar 21, 2020
@littledan
Copy link
Member

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 tc39/proposal-intl-numberformat-v3#1 .

@sffc sffc self-assigned this Jun 5, 2020
@Yaffle
Copy link

Yaffle commented May 20, 2021

@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
Copy link
Contributor

sffc commented May 20, 2021

@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
Copy link

Yaffle commented May 20, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: numbers Component: numbers, currency, units s: in progress Status: the issue has an active proposal Small Smaller change solvable in a Pull Request
Projects
Archived in project
Development

No branches or pull requests

4 participants