<!--
Summary provided to audience:
-->
<style>
/* make code examples suck less */
pre code {
margin: 0 !important;
font-size: 1.25em !important;
}
pre {
padding: 0 !important;
text-align: left !important;
}
.align-left {
text-align: left !important;
}
.small-li li {
font-size: 0.85em !important;
}
</style>
<!-- .slide: data-cover -->
# Decimal: Stage 1 Update
#### Jesse Alama & Nicolò Ribaudo
#### (Igalia, in partnership with Bloomberg)
#### October 2024
##### jesse@igalia.com
---
## Decimal
Exact decimal numbers to eliminate rounding errors frequently seen with binary floats when handling "human" numeric data, which is generally expressed in base 10.
**Example:** 1.3 *really is* 1.3, not an appoximation thereof.
**Example:** 0.1 + 0.2 and 0.3 represent the same quantity.
---
## Thank you
There has been great discussion about decimal in the TG3 weekly call and on GitHub issues
Thanks especially to Dan Ehrenberg, Mark Miller, Kris Kowal, Shane Carr, Jordan Harband, Nic Ribaudo, and other TG1, TG2, TG3 and even TG5 attendees for their helpful feedback! 🙏 (Any omissions are unintentional.)
---
## Guest speaker!
*(Jordan, take it away!)*
---
## Data model and API
* We're proposing to use IEEE 754 Decimal128
* A fixed bit-width for numbers provides a safe backdrop so that one can reason about how much data numbers can take up
* You can just do arithmetic without having to specify a precision.
* API consists basic arithmetic only.
---
## About those ...........000000000
---
## About those ...........000000000
The main use case for supporting trailing zeroes in the data model arose from Intl.
In the last plenary, we discussed how supporting trailing zeroes rules out the possibility that decimals would *ever* be a new primitive type.
---
## Preservation of precision in IEEE 754
IEEE 754 specifies how the precision of the inputs carries over into the precision of an operation. It might be unexpected!
**Example**: An item costs $40.00 and sales tax is 6.75%. Total cost is $42.70.
precision(40.00 + (40.00 * 0.0675)) = min(precision(40.00, precision(40.00 * 0.0675)) = min(-2, precision(40.00) + precision(0.0675)) = min(-2, -2 + -4) = -4.
So: 42.7000
---
## A realization about trailing zeroes
In discussions about whether the decimal data model should support trailing zeroes, we found out that the precision of a number (which encodes trailing zeroes) is generally needed only at the end.
<!--The propagation of precision throughout a computation is of little concern.-->
**Even if you use the automatic propagation, you almost certainly end up having to specify, at the end, what precision you want**.
```js
let x = complicatedCalculation(a, b, c);
return x.toFixed(2); // x may or may not have had 2 fractional digits
```
---
## Can we drop tracking of trailing zeroes from Decimal, while still satisfying all use cases?
---
## Can we drop tracking of trailing zeroes from Decimal, while still satisfying all use cases?
* ✅ Human-produced and human-consumable numeric quantities (e.g. money)
* ✅ Data exchange
* A loss of trailing zeroes might be problematic in some cases (though note that this is already true for binary floats)
* ✅ "More precise" floats
---
## Life without trailing zeroes
```js
let theAnswer = new Decimal128("42");
new Decimal128("42.0").equals(theAnswer); // true
new Decimal128("42.75").subtract(new Decimal128("0.75"))
.equals(theAnswer); // true
```
---
## Advantages of identifying Decimal128 cohort members
A cohort is a set of IEEE 754 Decimal128 values that are mathematically equal (think: `1.2` vs. `1.20`). We propose to not distinguish between cohort members.
* Simplifies mental model
* Less implementation complexity
* More future-proof for decimal primitives
---
## A "numeric values with precision" proposal
<div class="align-left small-li">
While the cost of tracking precision as part of `Decimal` outweighs the benefits, there are cases when it is significant:
- when representing physical measurements: "1.2 meters" and "1.20 meters"
- when displaying and pluralizing numeric values: "1 star" and "1.0 stars"
- when interacting with external numeric systems that do preserve/expose precision, to support round-tripping
</div>
---
## Hypothetical API example
```javascript
let numWithPrecision = 123.41.withFractionalDigits(1);
let decWithPrecision = new Decimal128("123.41").withFractionalDigits(-1);
numWithPrecision.valueOf(); // 123.4
numWithPrecision.numericObject; // Number { 123.4 }
numWithPrecision.fractionalDigits; // 1
decWithPrecision.valueOf(); // TypeError (decimal primitives are hidden)
decWithPrecision.numericObject; // Decimal { 120 }
decWithPrecision.fractionalDigits; // -1
new Intl.NumberFormat("it-IT").format(numWithPrecision);
```
---
## A "Numeric values with precision" proposal
We are introducing "numeric values with precision" as a separate proposal: [proposal-numeric-with-precision](https://github.com/nicolo-ribaudo/proposal-numeric-with-precision)
We are not proposing it for Stage 1 yet, because want first to coordinate with the champions of the not-yet-presented "numeric values with a unit" proposal.
---
## Blocking concerns have been overcome
We have satisfied concerns expresed in earlier plenaries:
* We reduced the scope of the proposal from new primitive type to new instantiable standard library object
* Removing quanta/precision (trailing zeroes support) clears the way for operator overloading *in the future* (not part of the current proposal)
* Supporting the main use case for trailing zeroes in a separate proposal
---
## Conclusion
- We have **simplified** the data model for decimal by removing support for quanta/precision, including trailing zeroes
- The Intl integration has been largely offloaded to the (very!) new "numeric value with precision" proposal (stay tuned for developments there, e.g. Ben Allen's stage 0 measure proposal!)
- [Spec text](http://tc39.es/proposal-decimal/) is complete and available
- [Polyfill](https://www.npmjs.com/package/decimal128) available
- *We believe we are essentially ready to ask for Stage 2* but we're not asking today
{"type":"slide","slideOptions":{"transition":"slide","theme":"igalia","controlsLayout":"edges","slideNumber":"c/t"}}