Open rakudrama opened 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.
@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).
@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.
@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?
Okay. From a discussion with @littledan, my understanding is that there are basically three options; we could do one, two, or all three:
const nf = new Intl.NumberFormat("en-US");
nf.format("1.23E4"); // => "12,300"
{ scale }
option to multiply the input number by a power of 10. We already do this when style="percent".
{ scale: -6 }
.
const nf = new Intl.NumberFormat("en-US", { scale: -3 });
nf.format(1230n); // ==> "1.23"
I plan to address this as part of my new proposal Intl.NumberFormat V3.
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 .
@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 , 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?
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.