You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We propose a `Decimal.Amount` object to store a Decimal value together with precision information. This is especially useful in formatting Decimal values, especially in internationalization and localization contexts.
let a =newDecimal.Amount("1.90", 4, "fractionalDigits");
81
+
constformatter=newIntl.NumberFormat("de-DE");
82
+
formatter.format(a); // "1,9000"
86
83
```
87
84
88
85
#### Why use JavaScript for this case?
89
86
90
-
Historically, JavaScript may not have been considered a language where exact decimal numbers are even representable, to say nothing of doing (exact) calculations. In some application architectures, JS only deals with a string representing a human-readable decimal quantity (e.g, `"1.25"`), and never does calculations or conversions. However, several trends push towards JS’s deeper involvement in with decimal quantities:
87
+
Historically, JavaScript may not have been considered a language where exact decimal numbers are even exactly representable, with the understanding that doing calculations is bound to propagate any initial rounding errors when numbers were created. In some application architectures, JS only deals with a string representing a human-readable decimal quantity (e.g, `"1.25"`), and never does calculations or conversions. However, several trends push towards JS’s deeper involvement in with decimal quantities:
91
88
92
89
-**More complicated frontend architectures**: Rounding, localization or other presentational aspects may be performed on the frontend for better interactive performance.
93
90
-**Serverless**: Many Serverless systems use JavaScript as a programming language in order to better leverage the knowledge of frontend engineers.
@@ -190,10 +187,12 @@ More host API interactions are discussed in [#5](https://github.com/tc39/proposa
190
187
191
188
## Specification and standards
192
189
193
-
Based on feedback from JS developers, engine implementors, and the members of the TC39 committee, we have nailed down a fairly concrete proposal. Please see the [spec text](https://github.com/tc39/proposal-decimal/blob/main/spec.emu) ([HTML version](https://github.com/tc39/proposal-decimal/blob/main/spec.emu)). are provided below. You’re encouraged to join the discussion by commenting on the issues linked below or [filing your own](https://github.com/tc39/proposal-decimal/issues/new).
190
+
Based on feedback from JS developers, engine implementors, and the members of the TC39 committee, we have a concrete proposal. Please see the [spec text](https://github.com/tc39/proposal-decimal/blob/main/spec.emu) ([HTML version](https://github.com/tc39/proposal-decimal/blob/main/spec.emu)). are provided below. You’re encouraged to join the discussion by commenting on the issues linked below or [filing your own](https://github.com/tc39/proposal-decimal/issues/new).
194
191
195
192
We will use the **Decimal128** data model for JavaScript decimals. Decimal128 is not a new standard; it was added to the IEEE 754 floating-point arithmetic standard in 2008. It represents the culmination of decades of research, both theoretical and practical, on decimal floating-point numbers. Values in the Decimal128 universe take up 128 bits. In this representation, up to 34 significant digits (that is, decimal digits) can be stored, with an exponent (power of ten) of +/- 6143.
196
193
194
+
In addition to proposing a new `Decimal` class, we propose a `Decimal.Amount` class for storing a Decimal number together with a precision (i.e., number of significant digits). The second class is important for string formatting purposes, where one desires to have a notion of a number that “knows” how precise it is.
@@ -239,33 +238,58 @@ With Decimal we do not envision a new literal syntax. One could consider one, su
239
238
240
239
### Data model
241
240
242
-
Decimal is based on IEEE 754 Decimal128, which is a standard for base-10 decimal numbers using 128 bits. We will offer a subset of the official Decimal128. There will be, in particular:
241
+
Decimal is based on IEEE 754-2019 Decimal128, which is a standard for base-10 decimal numbers using 128 bits. We will offer a subset of the official Decimal128. There will be, in particular:
243
242
244
-
- a single NaN value--distinct from the built-in `NaN` of JS. The difference between quiet and singaling NaNs will be collapsed into a single Decimal NaN.
243
+
- a single NaN value--distinct from the built-in `NaN` of JS. The difference between quiet and singaling NaNs will be collapsed into a single (quiet) Decimal NaN.
245
244
- positive and negative infinity will be available, though, as with `NaN`, they are distinct from JS's built-in `Infinity` and `-Infinity`.
246
245
247
-
Decimal canonicalizes when converting to strings and after performing arithmetic operations. This means that Decimals do not expose information about trailing zeroes. Thus, "1.20" is valid syntax, but there is no way to distinguish 1.20 from 1.2. This is an important omission from the capabilities defined by IEEE 754 Decimal128.
246
+
Decimal canonicalizes when converting to strings and after performing arithmetic operations. This means that Decimals do not expose information about trailing zeroes. Thus, "1.20" is valid syntax, but there is no way to distinguish 1.20 from 1.2. This is an important omission from the capabilities defined by IEEE 754 Decimal128. The `Decimal.Amount` class can be used to store an exact decimal value together with precision (number of significant digits), which can be used to track all digits of a number, including any trailing zeroes (which Decimal canonicalizes away).
247
+
248
+
The `Decimal.Amount` class will not support arithmetic or comparisons. Such operations should be delegated to the underlying Decimal value wrapped by a `Decimal.Amount`.
248
249
249
250
### Operator semantics
250
251
251
-
- Absolute value, negation, addition, multiplication, subtraction, division, and remainder are defined.
252
-
- Bitwise operators are not supported, as they don’t logically make sense on the Decimal domain ([#20](https://github.com/tc39/proposal-decimal/issues/20))
253
-
- rounding: All five rounding modes of IEEE 754—floor, ceiling, truncate, round-ties-to-even, and round-ties-away-from-zero—will be supported. (This implies that a couple of the rounding modes in `Intl.NumberFormat` and `Temporal` won't be supported.)
254
-
- We currently do not foresee Decimal values interacting with other Number values. Expect TypeErrors when trying to add, say, a Number to a Decimal, like for BigInt and Number. ([#10](https://github.com/tc39/proposal-decimal/issues/10)).
252
+
- Arithmetic
253
+
- Unary operations
254
+
- Absolute value
255
+
- Negation
256
+
- Binary operations
257
+
- Addition
258
+
- Multiplication
259
+
- Subtraction
260
+
- Division
261
+
- Remainder
262
+
- Rounding: All five rounding modes of IEEE 754—floor, ceiling, truncate, round-ties-to-even, and round-ties-away-from-zero—will be supported.
263
+
- (This implies that a couple of the rounding modes in `Intl.NumberFormat` and `Temporal` won't be supported.)
264
+
- Comparisons
265
+
- equals and not-equals
266
+
- less-than, less-than-or-equal
267
+
- greater-than, greater-than-or-equal
268
+
- Mantissa, exponent, significand
269
+
270
+
The library of numerical functions here is kept deliberately minimal. It is based around targeting the primary use case, in which fairly straightforward calculations are envisioned. The secondary use case (data exchange) will involve probably little or no calculation at all. For the tertiary use case of scientific/numerical computations, developers may experiment in JavaScript, developing such libraries, and we may decide to standardize these functions in a follow-on proposal; a minimal toolkit of mantissa, exponent, and significand will be available. We currently do not have good insight into the developer needs for this use case, except generically: square roots, exponentiation & logarithms, and trigonometric functions might be needed, but we are not sure if this is a complete list, and which are more important to have than others. In the meantime, one can use the various functions in JavaScript’s `Math` standard library.
271
+
272
+
### Unsupported operations
255
273
256
-
The library of numerical functions here is kept deliberately minimal. It is based around targeting the primary use case, in which fairly straightforward calculations are envisioned. The secondary use case (data exchange) will involve probably little or no calculation at all. For the tertiary use case of scientific/numerical computations, developers may experiment in JavaScript, developing such libraries, and we may decide to standardize these functions in a follow-on proposal. We currently do not have good insight into the developer needs for this use case, except generically: square roots, exponentiation & logarithms, and trigonometric functions might be needed, but we are not sure if this is a complete list, and which are more important to have than others. In the meantime, one can use the various functions in JavaScript’s `Math` standard library.
274
+
- Bitwise operators are not supported, as they don’t logically make sense on the Decimal domain ([#20](https://github.com/tc39/proposal-decimal/issues/20))
275
+
- We currently do not foresee Decimal values interacting with other Number values. That is, TypeErrors will be thrown when trying to add, say, a Number to a Decimal, similar to the situation with BigInt and Number. ([#10](https://github.com/tc39/proposal-decimal/issues/10)).
257
276
258
277
### Conversion to and from other data types
259
278
260
279
Decimal objects can be constructed from Numbers, Strings, and BigInts. Similarly, there will be conversion from Decimal objects to Numbers, String, and BigInts.
261
280
262
281
### String formatting
263
282
283
+
`Decimal` objects can be converted to Strings in a number of ways, similar to Numbers:
284
+
264
285
-`toString()` is similar to the behavior on Number, e.g., `new Decimal("123.456").toString()` is `"123.456"`. ([#12](https://github.com/tc39/proposal-decimal/issues/12))
265
286
-`toFixed()` is similar to Number's `toFixed()`
266
287
-`toPrecison()` is similar to Number's `toPrecision()`
267
288
-`toExponential()` is similar to Number's `toExponential()`
268
-
-`Intl.NumberFormat.prototype.format` should transparently support Decimal ([#15](https://github.com/tc39/proposal-decimal/issues/15))
289
+
-`Intl.NumberFormat.prototype.format` should transparently support Decimal ([#15](https://github.com/tc39/proposal-decimal/issues/15)), which will be handled via `Decimal.Amount` objects
290
+
-`Intl.PluralRules.prototype.select` should similarly support Decimal, in that it will support `Decimal.Amount` objects
291
+
292
+
In addition, the `Decimal.Amount` object will provide a `toString` method, which will render its underlying Decimal value according to its underlying precision.
0 commit comments