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
20 changes: 10 additions & 10 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '20.x'
- run: npm install
- run: npm run build
- name: commit changes
uses: elstudio/actions-js-build/commit@v4
with:
commitMessage: "fixup: [spec] `npm run build`"
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "20.x"
- run: npm install
- run: npm run build
- name: commit changes
uses: elstudio/actions-js-build/commit@v4
with:
commitMessage: "fixup: [spec] `npm run build`"
227 changes: 127 additions & 100 deletions README.md

Large diffs are not rendered by default.

66 changes: 34 additions & 32 deletions RELATED.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ The need for accurately representing decimal quantities is not new or unique to
### Related JS ecosystem libraries

JavaScript programmers are using decimal data types today with various ecosystem libraries. The most popular three on npm are each by [MikeMcl](https://github.com/mikemcl):

- [decimal.js](http://mikemcl.github.io/decimal.js/)
- [big.js](https://mikemcl.github.io/big.js/)
- [bignumber.js](https://mikemcl.github.io/bignumber.js/)

These packages have some [interesting differences](https://github.com/MikeMcl/big.js/wiki), but there are also many similarities:

- APIs are based on JavaScript objects and method calls
- Rounding modes and precision limits are settings in the constructor
- Inherently rounding operations like sqrt, exponentiation, division are supported
Expand All @@ -23,46 +25,46 @@ We plan to investigate the experiences and feedback developers have had with the
Due to the overwhelming evidence listed above that decimal is an important data type in programming, many different programming languages, databases and standards include decimal, rationals, or similar features. Below is a partial listing, with a summary of the semantics in each.

- Standards
- **IEEE 754**-2008 and later: 32-bit, 64-bit and 128-bit decimal; see [explanation](https://en.wikipedia.org/wiki/Decimal_floating_point#IEEE_754-2008_encoding) (recommends against using 32-bit decimal)
- (plus many of the below are standardized)
- **IEEE 754**-2008 and later: 32-bit, 64-bit and 128-bit decimal; see [explanation](https://en.wikipedia.org/wiki/Decimal_floating_point#IEEE_754-2008_encoding) (recommends against using 32-bit decimal)
- (plus many of the below are standardized)
- Programming languages
- Fixed-size decimals:
- **[C](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1312.pdf)**: 32, 64 and 128-bit IEE 754 decimal types, with a global settings object. Still a proposal, but has a GCC implementation.
- **[C++](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3871.html)**: Early proposal work in progress, to be based on IEEE 64 and 128-bit decimal. Still a proposal, but has a GCC implementation.
- **[C#](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/decimal)**/**[.NET](https://msdn.microsoft.com/en-us/library/system.decimal(v=vs.110).aspx)**: Custom 128-bit decimal semantics with slightly different sizes for the mantissa vs exponent compared to IEEE.
- **[Swift](https://developer.apple.com/documentation/foundation/decimal)**/**[Obj-C](https://developer.apple.com/documentation/foundation/nsdecimal?language=objc)**: Yet another custom semantics for fixed-bit-size floating point decimal.
- Global settings for setting decimal precision
- **[Python](https://docs.python.org/2/library/decimal.html)**: Decimal with global settings to set precision.
- Rationals
- **[Perl6](https://docs.perl6.org/type/Rat)**: Literals like `1.5` are Rat instances!
- **[Common Lisp](http://www.lispworks.com/documentation/lw50/CLHS/Body/t_ratio.htm#ratio)**: Ratios live alongside floats; no decimal data type
- **[Scheme](http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2)**: Analogous to Common Lisp, with different names for types (Racket is similar)
- **[Ruby](https://ruby-doc.org/core-2.6.5/Rational.html)**: Rational class alongside BigDecimal.
- Arbitrary-precision decimals (this proposal)
- **[Ruby](https://ruby-doc.org/stdlib-2.4.0/libdoc/bigdecimal/rdoc/BigDecimal.html)**: Arbitrary-precision Decimal, alongside Rational.
- **[PHP](http://php.net/manual/en/book.bc.php)**: A set of functions to bind to bc for mathematical calculations. An alternative community-driven [Decimal library](https://php-decimal.io/) is also available.
- **[Java](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/math/BigDecimal.html)**: Arbitrary-precision decimal based on objects and methods. Requires rounding modes and precision parameters for operations like division
- Fixed-size decimals:
- **[C](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1312.pdf)**: 32, 64 and 128-bit IEE 754 decimal types, with a global settings object. Still a proposal, but has a GCC implementation.
- **[C++](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3871.html)**: Early proposal work in progress, to be based on IEEE 64 and 128-bit decimal. Still a proposal, but has a GCC implementation.
- **[C#](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/decimal)**/**[.NET](<https://msdn.microsoft.com/en-us/library/system.decimal(v=vs.110).aspx>)**: Custom 128-bit decimal semantics with slightly different sizes for the mantissa vs exponent compared to IEEE.
- **[Swift](https://developer.apple.com/documentation/foundation/decimal)**/**[Obj-C](https://developer.apple.com/documentation/foundation/nsdecimal?language=objc)**: Yet another custom semantics for fixed-bit-size floating point decimal.
- Global settings for setting decimal precision
- **[Python](https://docs.python.org/2/library/decimal.html)**: Decimal with global settings to set precision.
- Rationals
- **[Perl6](https://docs.perl6.org/type/Rat)**: Literals like `1.5` are Rat instances!
- **[Common Lisp](http://www.lispworks.com/documentation/lw50/CLHS/Body/t_ratio.htm#ratio)**: Ratios live alongside floats; no decimal data type
- **[Scheme](http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2)**: Analogous to Common Lisp, with different names for types (Racket is similar)
- **[Ruby](https://ruby-doc.org/core-2.6.5/Rational.html)**: Rational class alongside BigDecimal.
- Arbitrary-precision decimals (this proposal)
- **[Ruby](https://ruby-doc.org/stdlib-2.4.0/libdoc/bigdecimal/rdoc/BigDecimal.html)**: Arbitrary-precision Decimal, alongside Rational.
- **[PHP](http://php.net/manual/en/book.bc.php)**: A set of functions to bind to bc for mathematical calculations. An alternative community-driven [Decimal library](https://php-decimal.io/) is also available.
- **[Java](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/math/BigDecimal.html)**: Arbitrary-precision decimal based on objects and methods. Requires rounding modes and precision parameters for operations like division
- Databases
- Decimal with precision configurable in the schema
- [Microsoft SQL Server](https://docs.microsoft.com/en-us/sql/t-sql/data-types/decimal-and-numeric-transact-sql)
- [PostgreSQL](https://www.postgresql.org/docs/9.1/static/datatype-numeric.html)
- [MySQL](https://dev.mysql.com/doc/refman/5.7/en/precision-math-decimal-characteristics.html)
- IEEE 754-2008 decimal
- Bloomberg's [comdb2](https://bloomberg.github.io/comdb2/decimals.html)
- [MongoDB](https://docs.mongodb.com/manual/core/shell-types/#shell-type-decimal)
- Decimal with precision configurable in the schema
- [Microsoft SQL Server](https://docs.microsoft.com/en-us/sql/t-sql/data-types/decimal-and-numeric-transact-sql)
- [PostgreSQL](https://www.postgresql.org/docs/9.1/static/datatype-numeric.html)
- [MySQL](https://dev.mysql.com/doc/refman/5.7/en/precision-math-decimal-characteristics.html)
- IEEE 754-2008 decimal
- Bloomberg's [comdb2](https://bloomberg.github.io/comdb2/decimals.html)
- [MongoDB](https://docs.mongodb.com/manual/core/shell-types/#shell-type-decimal)
- Libraries
- Intel C [inteldfp](https://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library): IEEE decimal
- Bloomberg C++ [bdldfp](https://github.com/bloomberg/bde/blob/master/groups/bdl/bdldfp/bdldfp_decimal.h): IEEE decimal
- IBM C [decnumber](http://speleotrove.com/decimal/decnumber.html): Configurable context with precision, rounding mode
- Rust crates [[1]](https://crates.io/crates/decimal) [[2]](https://crates.io/crates/bigdecimal)
- Intel C [inteldfp](https://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library): IEEE decimal
- Bloomberg C++ [bdldfp](https://github.com/bloomberg/bde/blob/master/groups/bdl/bdldfp/bdldfp_decimal.h): IEEE decimal
- IBM C [decnumber](http://speleotrove.com/decimal/decnumber.html): Configurable context with precision, rounding mode
- Rust crates [[1]](https://crates.io/crates/decimal) [[2]](https://crates.io/crates/bigdecimal)
- Hardware (all implementing IEEE decimal)
- [POWER6](https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/Power+Systems/page/POWER6+Decimal+Floating+Point+(DFP))
- [RISC-V](https://en.wikichip.org/wiki/risc-v/standard_extensions) (planned)
- [POWER6](<https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/Power+Systems/page/POWER6+Decimal+Floating+Point+(DFP)>)
- [RISC-V](https://en.wikichip.org/wiki/risc-v/standard_extensions) (planned)

### History of discussion of decimal in TC39

Decimal has been under discussion in TC39 for a very long time, with proposals and feedback from many people including Sam Ruby, Mike Cowlishaw, Brendan Eich, Waldemar Horwat, Maciej Stachowiak, Dave Herman and Mark Miller.

- A new `decimal` type was long planned for ES4, see [Proposed ECMAScript 4th Edition – Language Overview](https://www.ecma-international.org/activities/Languages/Language%20overview.pdf)
- In the following ES3.1/ES5 effort, discussions about a decimal type continued on es-discuss, e.g., [[1]](https://mail.mozilla.org/pipermail/es-discuss/2008-August/007244.html) [[2]](https://mail.mozilla.org/pipermail/es-discuss/2008-September/007466.html)
- Decimal was discussed at length in the development of ES6. It was eventually rolled into the broader typed objects/value types effort, which didn't make it into ES6, but is being incrementally developed now (see the below section about relationship to other TC39 proposals).

13 changes: 7 additions & 6 deletions decimal128-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ result is 0.8, and they also should be equivalent. However, since the result for
can't be exactly represented by binary floating-point numbers, the results diverge. For this example, the
reason for such difference on results comes from the fact that multiple additions using binary floating-point
numbers will carry more errors from rounding than a single multiplication. It's possible to see more examples
of issues like that on this [Decimal FAQ section](http://speleotrove.com/decimal/decifaq1.html#inexact). Such
of issues like that on this [Decimal FAQ section](http://speleotrove.com/decimal/decifaq1.html#inexact). Such
issue isn't a problem with Decimal128, because we are able to represent all those decimal fractions exactly,
including the intermediate results for arithmetic operations.

Expand Down Expand Up @@ -57,6 +57,7 @@ console.log(calculateBill(items, tax));
```

Here, you can see several elements of `Decimal128` at work:

- Create a `Decimal128` as a literal, e.g., `1.25m`, or convert one from another type, as `Decimal128(value)`.
- Add and multiply `Decimal128`s with the `+` and `*` operators.
- Round decimals with `Decimal128.round`, based on an options bag describing how to round.
Expand Down Expand Up @@ -305,7 +306,7 @@ console.log(isNotEqual); // prints false

#### Comparing Decimal128 with other primitive types

Since comparison operators uses mathematical value of operands, it is possible to compare Decimal128 other
Since comparison operators uses mathematical value of operands, it is possible to compare Decimal128 other
types like Numbers, BigInt or Strings.

```js
Expand Down Expand Up @@ -359,7 +360,7 @@ If a Decimal128 is an operand of a bitwise operator, it results in a `TypeError`

### `Decimal128.round(value [, options])`

This is the function to be used when there's need to round Decimal128 in some specific way. It rounds the
This is the function to be used when there's need to round Decimal128 in some specific way. It rounds the
Decimal128 passed as parameter, tanking in consideration `options`.

- `value`: A Decimal128 value. If the value is from another type, it throws `TypeError`.
Expand All @@ -371,12 +372,12 @@ Decimal128 passed as parameter, tanking in consideration `options`.
option is described below.
- `down`: round towards zero.
- `half down`: round towards "nearest neighbor". If both neighbors are equidistant, it rounds down.
- `half up`: round towards "nearest neighbor". If both neighbors are equidistant, it rounds up.
- `half up`: round towards "nearest neighbor". If both neighbors are equidistant, it rounds up.
- `half even`: round towards the "nearest neighbor". If both neighbors are equidistant, it rounds towards
the even neighbor.
- `up`: round away from zero.

```js
```js
let a = Decimal128.round(0.53m, {roundingMode: 'half up', maximumFractionDigits: 1});
assert(a, 0.5m);

Expand All @@ -391,7 +392,7 @@ assert(a, 0.3m);

a = Decimal128.round(0.31m, {roundingMode: 'up', maximumFractionDigits: 1});
assert(a, 0.4m);
```
```

### Decimal128.add(lhs, rhs [, options])

Expand Down
487 changes: 273 additions & 214 deletions index.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion intl.emu
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<h1>Decimal128.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )</h1>

<p>
This definition supersedes the definition provided in es2024, <emu-xref href="#sec-decimal128.prototype.tolocalestring"></emu-xref>.
This definition supersedes the definition provided in es2024, <emu-xref href="#sec-decimal.prototype.tolocalestring"></emu-xref>.
</p>

<p>
Expand Down
19 changes: 18 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"scripts": {
"start": "npm run build-loose -- --watch",
"build": "npm run build-loose -- --strict",
"build-loose": "ecmarkup --verbose --lint-spec --load-biblio @tc39/ecma262-biblio --load-biblio @tc39/ecma402-biblio spec.emu index.html"
"build-loose": "ecmarkup --verbose --lint-spec --load-biblio @tc39/ecma262-biblio --load-biblio @tc39/ecma402-biblio spec.emu index.html",
"format": "prettier . --write",
"lint": "prettier . --check"
},
"repository": {
"type": "git",
Expand All @@ -26,6 +28,7 @@
"devDependencies": {
"@tc39/ecma262-biblio": "2.1",
"@tc39/ecma402-biblio": "^2.1.1050",
"ecmarkup": "github:jessealama/ecmarkup#permit-decimal-subscript-D"
"ecmarkup": "github:jessealama/ecmarkup#permit-decimal-subscript-D",
"prettier": "^3.5.3"
}
}
Loading