Skip to content

Commit fb37598

Browse files
committed
Simplify examples
1 parent e6fbf04 commit fb37598

File tree

13 files changed

+201
-948
lines changed

13 files changed

+201
-948
lines changed

docs/cookbook.md

Lines changed: 67 additions & 144 deletions
Large diffs are not rendered by default.

docs/data-model.md

Lines changed: 22 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -6,48 +6,22 @@ The Decimal proposal uses a subset of the IEEE 754-2019 Decimal128 format. This
66

77
## IEEE 754-2019 Decimal128
88

9-
Decimal128 is part of the IEEE 754 standard for floating-point arithmetic, added in the 2008 revision. It provides:
10-
11-
- **128-bit representation**: Each decimal value is stored in exactly 128 bits
12-
- **Base-10 arithmetic**: Unlike binary floating-point, calculations are performed in base 10
13-
- **34 significant digits**: Up to 34 decimal digits of precision
14-
- **Exponent range**: -6143 to +6144 (base 10)
15-
16-
### Why Decimal128?
9+
Decimal128 is part of the IEEE 754 standard for floating-point arithmetic, added in the 2008 revision. (In fact, JS's Number type is also based on IEEE 754: binary64) It provides a 128-bit representation(each decimal value is stored in exactly 128 bits) for base-10 arithmetic with up to 34 significant digits and an exponent range of -6143 to +6144.
1710

1811
The choice of Decimal128 balances several considerations:
1912

2013
1. **Sufficient precision**: 34 digits covers virtually all practical use cases, including:
21-
- Financial calculations (even national debts)
14+
- Financial calculations (even very large values that don't occur in everyday scenarios)
2215
- Scientific measurements
23-
- Cryptocurrency (Bitcoin has 8 decimal places)
24-
2516
2. **Fixed size**: Unlike arbitrary-precision decimals, Decimal128 has predictable memory usage and performance characteristics
26-
27-
3. **Industry standard**: Implemented in hardware on some platforms and widely supported in other languages
28-
17+
3. **Industry standard**: Widely supported in other languages
2918
4. **Reasonable range**: Can represent values from ±10^-6143 to ±10^6144
3019

31-
## Representation Details
32-
33-
### Encoding Format
34-
35-
Decimal128 uses a specialized encoding that efficiently packs decimal digits into 128 bits:
36-
37-
```
38-
Sign (1 bit) | Combination field (17 bits) | Trailing significand (110 bits)
39-
```
40-
41-
The combination field encodes:
42-
- Two bits of the exponent
43-
- Whether the number is finite, infinite, or NaN
44-
- The most significant digit of the significand (for finite numbers)
45-
4620
### Special Values
4721

4822
#### NaN (Not a Number)
4923

50-
Decimal has a single, quiet NaN value:
24+
Decimal has a single, quiet NaN value, similar to JS's Number:
5125

5226
```javascript
5327
const nan = new Decimal("NaN");
@@ -58,8 +32,6 @@ nan.add(new Decimal("5")); // => NaN
5832
nan.multiply(new Decimal("0")); // => NaN
5933
```
6034

61-
Unlike IEEE 754 binary floating-point, Decimal does not distinguish between quiet and signaling NaNs.
62-
6335
#### Infinity
6436

6537
Positive and negative infinity are supported:
@@ -116,7 +88,7 @@ new Decimal("10").divide(new Decimal("3")).multiply(new Decimal("3")); // => 10
11688

11789
### Rounding
11890

119-
When a result would exceed 34 significant digits, rounding occurs:
91+
When a result would exceed 34 significant digits, the calculation is exact up to 34 digits with rounding occuring after the 34th digit:
12092

12193
```javascript
12294
// Division may require rounding
@@ -128,7 +100,7 @@ const result = a.divide(b); // => 0.3333333333333333333333333333333333 (34 digit
128100
The default rounding mode is "half even" (banker's rounding), but other modes are available:
129101

130102
- **halfEven**: Round to nearest, ties to even (default)
131-
- **halfAwayFromZero**: Round to nearest, ties away from zero
103+
- **halfExpand**: Round to nearest, ties away from zero
132104
- **ceil**: Round towards positive infinity
133105
- **floor**: Round towards negative infinity
134106
- **trunc**: Round towards zero
@@ -151,23 +123,23 @@ small.divide(new Decimal("10")); // => 0
151123

152124
### vs Number (binary64)
153125

154-
| Aspect | Number (IEEE 754 binary64) | Decimal (IEEE 754 Decimal128) |
155-
|--------|---------------------------|-------------------------------|
156-
| Base | Binary (base 2) | Decimal (base 10) |
157-
| Precision | ~15-17 decimal digits | Exactly 34 decimal digits |
158-
| Exact decimal representation | No | Yes |
159-
| Range | ±1.8×10^308 | ±9.999...×10^6144 |
160-
| Size | 64 bits | 128 bits |
161-
| Special values | ±0, ±Infinity, NaN | ±0, ±Infinity, NaN |
126+
| Aspect | Number (IEEE 754 binary64) | Decimal (IEEE 754 Decimal128) |
127+
| ---------------------------- | -------------------------- | ----------------------------- |
128+
| Base | Binary (base 2) | Decimal (base 10) |
129+
| Precision | ~15-17 decimal digits | Exactly 34 decimal digits |
130+
| Exact decimal representation | No | Yes |
131+
| Range | ±1.8×10^308 | ±9.999...×10^6144 |
132+
| Size | 64 bits | 128 bits |
133+
| Special values | ±0, ±Infinity, NaN | ±0, ±Infinity, NaN |
162134

163135
### vs BigInt
164136

165-
| Aspect | BigInt | Decimal |
166-
|--------|--------|---------|
167-
| Precision | Arbitrary | 34 significant digits |
168-
| Decimal fractions | No | Yes |
169-
| Memory usage | Variable | Fixed 128 bits |
170-
| Performance | Varies with size | Consistent |
137+
| Aspect | BigInt | Decimal |
138+
| ----------------- | ---------------- | --------------------- |
139+
| Precision | Arbitrary | 34 significant digits |
140+
| Non-integers | No | Yes |
141+
| Memory usage | Variable | Fixed 128 bits |
142+
| Performance | Varies with size | Consistent |
171143

172144
## Design Decisions
173145

@@ -185,10 +157,7 @@ const b = new Decimal("20");
185157
a.add(b); // => Decimal("30")
186158
```
187159

188-
This decision was made based on implementer feedback and concerns about:
189-
- Performance implications
190-
- Confusion with implicit conversions
191-
- Consistency with BigInt precedent
160+
This decision was made based on implementer feedback and concerns about performance implication, confusion with implicit conversions (given that Decimal is not proposed as a new primitive type).
192161

193162
### No Literal Syntax
194163

@@ -204,60 +173,8 @@ This simplifies the implementation and avoids syntax complexity.
204173

205174
### Canonicalization vs Cohort Preservation
206175

207-
IEEE 754 supports the concept of "cohorts" - different representations of the same value (e.g., 1.20 vs 1.2). The Decimal proposal canonicalizes values, not preserving cohorts:
176+
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:
208177

209178
```javascript
210179
new Decimal("1.20").toString(); // => "1.2" (trailing zero lost)
211180
```
212-
213-
## Implementation Considerations
214-
215-
### Memory Layout
216-
217-
Each Decimal value occupies 128 bits (16 bytes). Implementations may choose to:
218-
- Store inline for small objects
219-
- Use tagged pointers
220-
- Allocate on heap for compatibility
221-
222-
### Performance
223-
224-
Expected performance characteristics:
225-
- **Addition/Subtraction**: Similar to integer operations with normalization
226-
- **Multiplication**: More complex than binary, but hardware acceleration possible
227-
- **Division**: Most expensive operation, may require iterative algorithms
228-
- **Comparison**: Fast, often just integer comparison of encoded form
229-
230-
### Platform Support
231-
232-
Some platforms provide hardware support for Decimal128:
233-
- IBM POWER (Power6 and later)
234-
- IBM System z
235-
- Some Intel processors (via libraries)
236-
237-
On platforms without hardware support, software implementations are used.
238-
239-
## Future Considerations
240-
241-
### Decimal256
242-
243-
For applications requiring more than 34 digits, a future proposal might add Decimal256 (70 digits). The current API is designed to be extensible.
244-
245-
### Arbitrary Precision
246-
247-
Some use cases might benefit from arbitrary-precision decimals (BigDecimal). This could be a separate type that interoperates with Decimal128.
248-
249-
### Operator Overloading
250-
251-
If JavaScript adds general operator overloading, Decimal could be updated to support arithmetic operators while maintaining backward compatibility with the method-based API.
252-
253-
## Summary
254-
255-
The Decimal data model provides:
256-
- Exact decimal arithmetic for 34 significant digits
257-
- IEEE 754-2019 standard compliance
258-
- Predictable performance and memory usage
259-
- Special value handling (NaN, Infinity)
260-
- Multiple rounding modes
261-
- Clear semantics without implicit conversions
262-
263-
This design balances the needs of financial calculations, data exchange, and general decimal arithmetic while maintaining implementation feasibility across JavaScript engines.

docs/decimal.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ All rounding methods follow IEEE 754-2019 rounding modes.
213213
Rounds to a given number of decimal places.
214214

215215
**Parameters:**
216+
216217
- `scale` (number): Number of decimal places to round to (default: 0)
217218
- `options.roundingMode` (string): One of "ceil", "floor", "trunc", "halfEven" (default), or "halfAwayFromZero"
218219

@@ -341,4 +342,3 @@ Returns the string representation. This method is called by JavaScript when a pr
341342
```js
342343
new Decimal("123.45").valueOf(); // => "123.45"
343344
```
344-

docs/index.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ A `Decimal` represents an exact base-10 decimal number using IEEE 754-2019 Decim
2424
```js
2525
const price = new Decimal("19.99");
2626
const quantity = new Decimal("3");
27-
const total = price.multiply(quantity); // => Decimal("59.97")
28-
total.toString(); // => "59.97"
27+
const total = price.multiply(quantity).toString(); // "59.97"
2928
```
3029

3130
Unlike JavaScript's `Number` type, Decimal provides exact decimal arithmetic:
@@ -37,7 +36,9 @@ Unlike JavaScript's `Number` type, Decimal provides exact decimal arithmetic:
3736
// With Decimal
3837
const a = new Decimal("0.1");
3938
const b = new Decimal("0.2");
40-
a.add(b).toString(); // => "0.3"
39+
const c = a.add(b);
40+
c.toString(); // "0.3"
41+
c.equals(new Decimal("0.3")); // true
4142
```
4243

4344
See [Decimal Documentation](./decimal.md) for detailed documentation.
@@ -48,7 +49,7 @@ Decimal uses a subset of the IEEE 754-2019 Decimal128 specification:
4849

4950
- **128-bit representation** allowing up to 34 significant digits
5051
- **Base-10 exponent** range of -6143 to +6144
51-
- **Special values**: NaN, positive and negative infinity
52+
- **Special values**: NaN, positive and negative infinity for compatibility with IEEE 754 and JS's `Number`
5253
- **Canonicalization**: values are normalized (e.g., "1.20" becomes "1.2")
5354

5455
For a detailed explanation of the data model and design decisions, see [Data Model Documentation](./data-model.md).
@@ -61,7 +62,7 @@ All Decimal values can be converted to and from strings:
6162
// Parsing
6263
const d1 = new Decimal("123.456");
6364
const d2 = new Decimal("-0.0078");
64-
const d3 = new Decimal("6.022e23"); // Scientific notation
65+
const d3 = new Decimal("6.022e23");
6566

6667
// Formatting
6768
d1.toString(); // => "123.456"
@@ -74,8 +75,9 @@ d1.toPrecision(5); // => "123.46"
7475

7576
### Financial Calculations
7677

78+
#### Calculate bill with tax
79+
7780
```js
78-
// Calculate bill with tax
7981
function calculateTotal(subtotal, taxRate) {
8082
const subtotalDec = new Decimal(subtotal);
8183
const taxRateDec = new Decimal(taxRate);
@@ -87,7 +89,7 @@ const total = calculateTotal("99.99", "0.0825");
8789
console.log(total.toFixed(2)); // => "108.24"
8890
```
8991

90-
### Currency Conversion
92+
#### Currency Conversion
9193

9294
```js
9395
const amountUSD = new Decimal("100.00");
@@ -96,11 +98,9 @@ const amountEUR = amountUSD.multiply(exchangeRate);
9698
console.log(amountEUR.toFixed(2)); // => "85.00"
9799
```
98100

99-
100-
101101
## Other Documentation
102102

103103
- [Why Decimal?](./why-decimal.md) — Understanding the motivation and use cases for Decimal
104104
- [API Reference](./decimal.md) — Complete API documentation for Decimal
105105
- [Cookbook](./cookbook.md) — Common recipes and patterns for working with Decimal
106-
- [Data Model](./data-model.md) — Detailed explanation of the IEEE 754-2019 Decimal128 subset
106+
- [Data Model](./data-model.md) — Detailed explanation of the IEEE 754-2019 Decimal128 subset

docs/node_modules/.package-lock.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)