-
Notifications
You must be signed in to change notification settings - Fork 2
/
spec.html
366 lines (338 loc) · 13.9 KB
/
spec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
<pre class=metadata>
title: ES BigInt Math (2021)
status: proposal
stage: 1
location: https://github.com/js-choi/proposal-bigint-math
copyright: false
contributors: J. S. Choi
</pre>
<script src=ecmarkup.js defer></script>
<link rel=stylesheet href=ecmarkup.css>
<emu-intro id=introduction>
<h1>Introduction</h1>
<p>This is the formal specification for a proposed extension
of the `Math` JavaScript global object with BigInt operations.
It modifies the original <a
href=https://tc39.github.io/ecma262/>ECMAScript specification</a> with
several new or revised clauses. See <a
href=https://github.com/js-choi/proposal-bigint-math/blob/main/README.md>the proposal's
explainer</a> for the proposal's background, motivation, and usage examples.</p>
</emu-intro>
<emu-clause id="sec-ecmascript-data-types-and-values" aoid="Type">
<h1>ECMAScript Data Types and Values</h1>
<emu-clause id="sec-ecmascript-language-types">
<h1>ECMAScript Language Types</h1>
<emu-clause id="sec-numeric-types">
<h1>Numeric Types</h1>
<emu-note type=editor>
<p>This section augments the <a
href=https://tc39.es/ecma262/#sec-numeric-types>original
Numeric Types clause</a>.</p>
</emu-note>
<p>ECMAScript has two built-in numeric types: Number and BigInt. In this specification, every numeric type _T_ contains a multiplicative identity value denoted _T_::unit. The specification types also have the following abstract operations, likewise denoted _T_::<i>op</i> for a given operation with specification name <i>op</i>. All argument types are _T_. The "Result" column shows the return type, along with an indication if it is possible for some invocations of the operation to return an abrupt completion.</p>
<emu-table id="table-numeric-type-ops" caption="Numeric Type Operations">
<table>
<tbody>
<tr>
<th>
Invocation Synopsis
</th>
<th>
Example source
</th>
<th>
Invoked by the Evaluation semantics of ...
</th>
<th>
Result
</th>
</tr>
<tr>
<td>
<ins>_T_::abs(x)</ins>
</td>
<td>
<ins>`Math.abs(x)`</ins>
</td>
<td><ins><emu-xref href="#sec-math.abs" title></emu-xref></ins>
</td>
<td>
<ins>_T_</ins>
</td>
</tr>
<tr>
<td>
<ins>_T_::exponentiate(x)</ins>
</td>
<td>
<ins>`Math.sign(x)`</ins>
</td>
<td><ins><emu-xref href="#sec-math.sign" title></emu-xref></ins>
</td>
<td>
<ins>_T_</ins>
</td>
</tr>
<tr>
<td>
<ins>_T_::sign(x)</ins>
</td>
<td>
<ins>`Math.sign(x)`</ins>
</td>
<td><ins><emu-xref href="#sec-math.sign" title></emu-xref></ins>
</td>
<td>
<ins>_T_</ins>
</td>
</tr>
<tr>
<td>
<ins>_T_::sqrt(x)</ins>
</td>
<td>
<ins>`Math.sqrt(x)`</ins>
</td>
<td><ins><emu-xref href="#sec-math.sqrt" title></emu-xref></ins>
</td>
<td>
<ins>_T_</ins>
</td>
</tr>
</tbody>
</table>
</emu-table>
<emu-clause id="sec-ecmascript-language-types-number-type">
<h1>The Number Type</h1>
<ins class="block">
<emu-clause id="sec-numeric-types-number-abs" type="numeric method">
<h1>
Number::abs (
_x_: a Number,
)
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If _x_ is *NaN*, return *NaN*.
1. If _x_ is *-0*<sub>𝔽</sub>, return *+0*<sub>𝔽</sub>.
1. If _x_ is *-∞*<sub>𝔽</sub>, return *+∞*<sub>𝔽</sub>.
1. If _x_ < *+0*<sub>𝔽</sub>, return -_x_.
1. Return _x_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-numeric-types-number-sign" type="numeric method">
<h1>
Number::sign (
_x_: a Number,
)
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Let _n_ be ? ToNumber(_x_).
1. If _n_ is *NaN*, _n_ is *+0*<sub>𝔽</sub>, or _n_ is *-0*<sub>𝔽</sub>, return _n_.
1. If _n_ < *+0*<sub>𝔽</sub>, return *-1*<sub>𝔽</sub>.
1. Return *1*<sub>𝔽</sub>.
</emu-alg>
</emu-clause>
<emu-clause id="sec-numeric-types-number-sqrt" type="numeric method">
<h1>
Number::sqrt (
_x_: a Number,
)
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If _x_ is *NaN*, _x_ is *+0*<sub>𝔽</sub>, _x_ is *-0*<sub>𝔽</sub>, or _x_ is *+∞*<sub>𝔽</sub>, return _x_.
1. If _x_ < *+0*<sub>𝔽</sub>, return *NaN*.
1. Return an implementation-approximated value that represents the result of the square root of ℝ(_x_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-ecmascript-language-types-bigint-type">
<h1>The BigInt Type</h1>
<ins class="block">
<emu-clause id="sec-numeric-types-bigint-abs" type="numeric method">
<h1>
BigInt::abs (
_x_: a BigInt,
)
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Return the BigInt value that represents abs(ℝ(_x_)).
</emu-alg>
</emu-clause>
<emu-clause id="sec-numeric-types-bigint-sign" type="numeric method">
<h1>
BigInt::sign (
_x_: a BigInt,
)
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If _x_ is *0*<sub>ℤ</sub>, return _x_.
1. If _x_ < *0*<sub>ℤ</sub>, return *-1*<sub>ℤ</sub>.
1. Return *1*<sub>ℤ</sub>.
</emu-alg>
</emu-clause>
<emu-clause id="sec-numeric-types-bigint-sqrt" type="numeric method">
<h1>
BigInt::sqrt (
_x_: a BigInt,
)
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If _x_ < *0*<sub>ℤ</sub>, throw a *RangeError* exception.
1. Let _root_ be the result of the square root of ℝ(_x_).
1. Return the BigInt value that represents _root_ rounded towards 0 to the next integer value.
</emu-alg>
</emu-clause>
</ins>
</emu-clause>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="sec-numbers-and-dates">
<h1>Numbers and Dates</h1>
<emu-clause id="sec-math-object">
<h1>The Math Object</h1>
<emu-clause id="sec-function-properties-of-the-math-object">
<h1>Function Properties of the Math Object</h1>
<emu-note type=editor>
<p>This section augments the <a
href=https://tc39.es/ecma262/#sec-function-properties-of-the-math-object>original
Function Properties of the Math Object clause</a>.</p>
</emu-note>
<emu-clause id="sec-math.abs">
<h1>Math.abs ( _x_ )</h1>
<p>Returns the absolute value of _x_; the result has the same magnitude as _x_ but has positive sign.</p>
<p>When the `Math.abs` method is called with argument _x_, the following steps are taken:</p>
<del class="block">
<emu-alg>
1. Let _n_ be ? ToNumber(_x_).
1. If _n_ is *NaN*, return *NaN*.
1. If _n_ is *-0*<sub>𝔽</sub>, return *+0*<sub>𝔽</sub>.
1. If _n_ is *-∞*<sub>𝔽</sub>, return *+∞*<sub>𝔽</sub>.
1. If _n_ < *+0*<sub>𝔽</sub>, return -_n_.
1. Return _n_.
</emu-alg>
</del>
<ins class="block">
<emu-alg>
1. Let _n_ be ? ToNumeric(_x_).
1. Let _T_ be Type(_n_).
1. Return ! _T_::abs(_n_).
</emu-alg>
</ins>
</emu-clause>
<emu-clause id="sec-math.max">
<h1>Math.max ( ..._args_ )</h1>
<p>Given zero or more arguments, calls <del>ToNumber</del><ins>ToNumeric</ins> on each of the arguments and returns the largest of the resulting values. <ins>When multiple arguments share the same mathematical value, then the latest argument is returned.</ins></p>
<p>When the `Math.max` method is called with zero or more arguments which form the rest parameter ..._args_, the following steps are taken:</p>
<emu-alg>
1. Let _coerced_ be a new empty List.
1. For each element _arg_ of _args_, do
1. Let _n_ be ? <del>ToNumber</del><ins>ToNumeric</ins>(_arg_).
1. Append _n_ to _coerced_.
1. Let _highest_ be *-∞*<sub>𝔽</sub>.
1. For each element _number_ of _coerced_, do
1. If _number_ is *NaN*, return *NaN*.
1. If _number_ is *+0*<sub>𝔽</sub> and _highest_ is *-0*<sub>𝔽</sub>, set _highest_ to *+0*<sub>𝔽</sub>.
1. If <del>_number_ > _highest_</del><ins>ℝ(_number_) ≥ ℝ(_highest_)</ins>, set _highest_ to _number_.
1. Return _highest_.
</emu-alg>
<emu-note>
<p>The comparison of values to determine the largest value is done using the IsLessThan algorithm except that *+0*<sub>𝔽</sub> is considered to be larger than *-0*<sub>𝔽</sub>.</p>
</emu-note>
<p>The *"length"* property of the `max` method is *2*<sub>𝔽</sub>.</p>
</emu-clause>
<emu-clause id="sec-math.min">
<h1>Math.min ( ..._args_ )</h1>
<p>Given zero or more arguments, calls <del>ToNumber</del><ins>ToNumeric</ins> on each of the arguments and returns the smallest of the resulting values. <ins>When multiple arguments share the same mathematical value, then the earliest argument is returned.</ins></p>
<p>When the `Math.min` method is called with zero or more arguments which form the rest parameter ..._args_, the following steps are taken:</p>
<emu-alg>
1. Let _coerced_ be a new empty List.
1. For each element _arg_ of _args_, do
1. Let _n_ be ? <del>ToNumber</del><ins>ToNumeric</ins>(_arg_).
1. Append _n_ to _coerced_.
1. Let _lowest_ be *+∞*<sub>𝔽</sub>.
1. For each element _number_ of _coerced_, do
1. If _number_ is *NaN*, return *NaN*.
1. If _number_ is *-0*<sub>𝔽</sub> and _lowest_ is *+0*<sub>𝔽</sub>, set _lowest_ to *-0*<sub>𝔽</sub>.
1. If <del>_number_ < _lowest_</del><ins>ℝ(_number_) < ℝ(_lowest_)</ins>, set _lowest_ to _number_.
1. Return _lowest_.
</emu-alg>
<emu-note>
<p>The comparison of values to determine the largest value is done using the IsLessThan algorithm except that *+0*<sub>𝔽</sub> is considered to be larger than *-0*<sub>𝔽</sub>.</p>
</emu-note>
<p>The *"length"* property of the `min` method is *2*<sub>𝔽</sub>.</p>
</emu-clause>
<emu-clause id="sec-math.pow">
<h1>Math.pow ( _base_, _exponent_ )</h1>
<p>When the `Math.pow` method is called with arguments _base_ and _exponent_, the following steps are taken:</p>
<del class="block">
<emu-alg>
1. Set _base_ to ? ToNumber(_base_).
1. Set _exponent_ to ? ToNumber(_exponent_).
1. Return ! Number::exponentiate(_base_, _exponent_).
</emu-alg>
</del>
<ins class="block">
<emu-alg>
1. Set _base_ to ? ToNumeric(_base_).
1. Set _exponent_ to ? ToNumeric(_exponent_).
1. If Type(_base_) is different from Type(_exponent_), throw a *TypeError* exception.
1. Let _T_ be Type(_base_).
1. Return ! _T_::exponentiate(_base_, _exponent_).
</emu-alg>
</ins>
</emu-clause>
<emu-clause id="sec-math.sign">
<h1>Math.sign ( _x_ )</h1>
<p>Returns the sign of _x_, indicating whether _x_ is positive, negative, or zero.</p>
<p>When the `Math.sign` method is called with argument _x_, the following steps are taken:</p>
<del class="block">
<emu-alg>
1. Let _n_ be ? ToNumber(_x_).
1. If _n_ is *NaN*, _n_ is *+0*<sub>𝔽</sub>, or _n_ is *-0*<sub>𝔽</sub>, return _n_.
1. If _n_ < *+0*<sub>𝔽</sub>, return *-1*<sub>𝔽</sub>.
1. Return *1*<sub>𝔽</sub>.
</emu-alg>
</del>
<ins class="block">
<emu-alg>
1. Let _n_ be ? ToNumeric(_x_).
1. Let _T_ be Type(_n_).
1. Return ! _T_::sign(_n_).
</emu-alg>
</ins>
</emu-clause>
<emu-clause id="sec-math.sqrt">
<h1>Math.sqrt ( _x_ )</h1>
<p>Returns the square root of _x_.</p>
<p>When the `Math.sqrt` method is called with argument _x_, the following steps are taken:</p>
<del class="block">
<emu-alg>
1. Let _n_ be ? ToNumber(_x_).
1. If _n_ is *NaN*, _n_ is *+0*<sub>𝔽</sub>, _n_ is *-0*<sub>𝔽</sub>, or _n_ is *+∞*<sub>𝔽</sub>, return _n_.
1. If _n_ < *+0*<sub>𝔽</sub>, return *NaN*.
1. Return an implementation-approximated value representing the result of the square root of ℝ(_n_).
</emu-alg>
</del>
<ins class="block">
<emu-alg>
1. Let _n_ be ? ToNumeric(_x_).
1. Let _T_ be Type(_n_).
1. Return ! _T_::sqrt(_n_).
</emu-alg>
</ins>
</emu-clause>
</emu-clause>
</emu-clause>
</emu-clause>