Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 144 additions & 73 deletions README.md

Large diffs are not rendered by default.

70 changes: 0 additions & 70 deletions RELATED.md

This file was deleted.

14 changes: 7 additions & 7 deletions docs/data-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,19 @@ posZero.equals(negZero); // => true
Object.is(posZero, negZero); // => false
```

### Canonicalization
### Normalization on the way out

Decimal values are canonicalized, meaning different representations of the same mathematical value are normalized:
Decimal never exposes trailing zeroes: different representations of the same mathematical value are indistinguishable. Equality compares mathematical values, and `toString` always renders a normalized String:

```javascript
// These all become the same Decimal value
// These all expose the same Decimal value
new Decimal("1.20").toString(); // => "1.2"
new Decimal("1.200").toString(); // => "1.2"
new Decimal("01.2").toString(); // => "1.2"
new Decimal("1.2e0").toString(); // => "1.2"
```

This is a deliberate departure from the full IEEE 754 standard, which preserves trailing zeros.
This is a guarantee about what Decimal *exposes*, not a requirement on how a value is *stored*. An implementation of Decimal may keep values unnormalized internally. But it must render a Decimal as a String, and compare Decimal values, by mathematical value (i.e., without trailing zeroes). We call this "normalize on the way out". This hybrid approach captures the performance benefits of [unnormalized decimal arithmetic](https://speleotrove.com/decimal/decifaq4.html) without exposing display precision to callers.

## Arithmetic Operations

Expand Down Expand Up @@ -171,10 +171,10 @@ const decimal = new Decimal("10.5");

This simplifies the implementation and avoids syntax complexity.

### Canonicalization vs Cohort Preservation
### Cohorts

IEEE 754 supports the concept of "cohorts", which are different representations of the same value (e.g., 1.20 vs 1.2). The Decimal proposal canonicalizes values, not preserving cohorts:
IEEE 754 supports the concept of "cohorts", which are different representations of the same value (e.g., 1.20 vs 1.2). An implementation of Decimal may preserve cohort members internally, but it never *exposes* which member a value belongs to. Trailing zeroes are thus not observable:

```javascript
new Decimal("1.20").toString(); // => "1.2" (trailing zero lost)
new Decimal("1.20").toString(); // => "1.2"
```
2 changes: 1 addition & 1 deletion docs/decimal.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ total.toString(); // => "21.64"
```
<!-- prettier-ignore-end -->

`Decimal` values are canonicalized, meaning that different representations of the same mathematical value are normalized. For example, "1.20" and "1.2" both result in the same `Decimal` value.
`Decimal` never exposes trailing zeroes: different representations of the same mathematical value are indistinguishable. For example, "1.20" and "1.2" compare as equal and render identically with `toString`. (An implementation may store values unnormalized internally and normalize only on the way out, when rendering or comparing.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`Decimal` never exposes trailing zeroes: different representations of the same mathematical value are indistinguishable. For example, "1.20" and "1.2" compare as equal and render identically with `toString`. (An implementation may store values unnormalized internally and normalize only on the way out, when rendering or comparing.)
`Decimal` never exposes trailing zeroes: different representations of the same mathematical value are indistinguishable. For example, "1.20" and "1.2" compare as equal and render identically with `toString`. An implementation may store values unnormalized internally and normalize only on the way out, when rendering or comparing.


## Constructor

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Decimal uses a subset of the IEEE 754-2019 Decimal128 specification:
- **128-bit representation** allowing up to 34 significant digits
- **Base-10 exponent** range of -6143 to +6144
- **Special values**: NaN, positive and negative infinity for compatibility with IEEE 754 and JS's `Number`
- **Canonicalization**: values are normalized (e.g., "1.20" becomes "1.2")
- **Normalization on the way out**: trailing zeroes are never exposed, so "1.20" and "1.2" are indistinguishable (implementations may store values unnormalized internally)

For a detailed explanation of the data model and design decisions, see [Data Model Documentation](./data-model.md).

Expand Down
Loading
Loading