-
Notifications
You must be signed in to change notification settings - Fork 18
/
spec.emu
1158 lines (1112 loc) Β· 67.4 KB
/
spec.emu
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
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="stylesheet" href="./spec.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">
<script src="./spec.js"></script>
<pre class="metadata">
title: Decimal
status: proposal
stage: 1
contributors: Jesse Alama, Waldemar Horwat
location: https://github.com/tc39/proposal-decimal/
</pre>
<emu-intro id="sec-decimal-intro-">
<h1>Introduction</h1>
<p>This specification consists of two parts:</p>
<ul>
<li>The specification of the <a href="https://github.com/tc39/proposal-decimal/" title="Decimal proposal (GitHub)">Decimal proposal</a> and everything related to it, proposed to be added to ECMA-262 in new sections;</li>
<li>A list of amendments to be made to ECMA-402.</li>
</ul>
</emu-intro>
<emu-clause id="sec-the-decimal-object">
<h1>The Decimal128 Object</h1>
<emu-intro id="sec-decimal-intro">
<h1>Introduction</h1>
<p>Decimal128 values, as specified here, are intended to represent base-10 (decimal) numbers as specified in <emu-xref href="#sec-bibliography">IEEE 754-2019 Decimal128</emu-xref>. Only a subset of the values specified in IEEE 754-2019 Decimal128 are modeled here, namely, the set of *canonicalized* values, which can be intuitively understood as decimal numbers without trailing zeroes. A Decimal128 value, as specified here, is one of the following six kinds of values:</p>
<ul>
<li>*NaN*<sub>π»</sub>, represending a decimal not-a-number</li>
<li>*+β*<sub>π»</sub>, representing positive infinity as a decimal,</li>
<li>*-β*<sub>π»</sub>, representing negative infinity as a decimal,</li>
<li>*+0*<sub>π»</sub>, represending non-negative zero as a decimal value</li>
<li>*β0*<sub>π»</sub>, representing negative zero as a decimal value, or</li>
<li>a mathematical value _v_ for which there exists an integer _q_ satisfing the following conditions:</li>
<ul>
<li>-6176 β€ _q_ β€ 6111,</li>
<li>v Γ 10<sup>β_q_</sup> is an integer _n_ such that 0 < abs(_n_) < 10<sup>34</sup></li>
</ul>
</ul>
<emu-note>
<p>A Decimal128 value is not an ECMAScript language value.</p>
</emu-note>
<p>A Decimal128 value is said to be <dfn id="dfn-decimal128-finite">finite</dfn> if it is either a mathematical value, *+0*<sub>π»</sub> or *-0*<sub>π»</sub>. A <dfn id="dfn-decimal128-zero">zero</dfn> Decimal128 value is one of *+0*<sub>π»</sub> or *-0*<sub>π»</sub>. A finite non-zero Decimal128 value is a mathematical value satisfying the conditions listed above.</p>
<p>The <dfn id="decimal128-mathematical-value">mathematical value</dfn> <emu-eqn id="dfn-decimal128-mv" aoid="MV">MV(_x_)</emu-eqn> of a finite Decimal128 value _x_ is defined as follows:</p>
<ul>
<li>MV(*+0*<sub>π»</sub>) = 0</li>
<li>MV(*-0*<sub>π»</sub>) = 0</li>
<li>MV(_v_) = _v_ (provided _v_ is neither *+0*<sub>π»</sub> nor *-0*<sub>π»</sub>)</li>
</ul>
<p>Decimal128 values defined in this section are ECMAScript analogues of <emu-xref href="#sec-bibliography">IEEE 754-2019 Decimal128 values</emu-xref>. It is important to note that the full spectrum of values defined by IEEE 754-2019 Decimal128 are not available here, namely non-canonical Decimal128 values, which can be underdtood as values containing trailing zeroes. Also, this specification simplifies IEEE 754-2019 Decimal128 in a further way: there is only one Decimal128 value, NaN<sub>π»</sub>, representing all possible IEEE 754-2019 Decimal128 NaN values.</p>
<p>A <dfn id="dfn-decimal128-rounding-mode">Decimal128 rounding mode</dfn> is one of the String values *"ceil"*, *"floor"*, *"trunc"*, *"halfExpand"*, and *"halfEven"*. The <dfn id="dfn-decimal128-default-rounding-mode">default rounding mode</dfn> is the String value *"halfEven"*.</p>
<emu-table id="table-decimal128-rounding-modes">
<emu-caption>Rounding modes in Decimal128 compared to IEEE 754-2019 rounding modes</emu-caption>
<table class="real-table">
<thead>
<tr>
<th>Decimal128 rounding mode</th>
<th>Description</th>
<th>IEEE 754-2019 rounding mode</th>
</tr>
</thead>
<tbody>
<tr>
<td>*"ceil"*</td>
<td>Toward positive infinity</td>
<td>*"roundTowardPositive"*</td>
</tr>
<tr>
<td>*"floor"*</td>
<td>Toward negative infinity</td>
<td>*"roundTowardNegative"*</td>
</tr>
<tr>
<td>*"trunc"*</td>
<td>Toward zero</td>
<td>*"roundTowardZero"*</td>
</tr>
<tr>
<td>*"halfExpand"*</td>
<td>Ties away from zero</td>
<td>*"roundTiesToAway"*</td>
</tr>
<tr>
<td>*"halfEven"*</td>
<td>Ties toward an even rounding increment multiple</td>
<td>*"roundTiesToEven"*</td>
</tr>
</tbody>
</table>
<emu-note>The above five rounding modes are defined in IEEE 754-2019. This table is offered for implementors who may need to convert the Decimal128 rounding modes defined here into a library that may use the official IEEE 754-2019 rounding mode names. Additional rounding modes are used elsewhere in this specification, such as in <emu-xref href="#table-intl-rounding-modes">Intl.NumberFormat</emu-xref>.</emu-note>
</emu-table>
<p>For every non-NaN Decimal128 value, we define its <emu-eqn id="dfn-decimal128-sign" aoid="sign">sign</emu-eqn> as follows:</p>
<ul>
<li>sign(*+β*<sub>π»</sub>) = 1</li>
<li>sign(*-β*<sub>π»</sub>) = -1</li>
<li>sign(*+0*<sub>π»</sub>) = 1</li>
<li>sign(*β0*<sub>π»</sub>) = -1</li>
<li>sign(_v_) = _v_ / abs(_v_) for all other Decimal128 values _v_</li>
</ul>
<p>For every finite non-zero Decimal128 value _v_ there exists a unique integer _e_ and mathematical value _s_ such that</p>
<ol>
<li>_v_ = _s_ Γ 10<sup>_e_</sup></li>
<li>1 β€ abs(_s_) < 10</li>
</ol>
<p>We call _e_ the <dfn id="dfn-decimal128-exponent">exponent</dfn> and _s_ the <dfn id="dfn-decimal128-significand">significand</dfn> of _v_. The exponent and significand are undefined for NaN, non-finite, and zero Decimal128 values.</p>
<emu-note>
<p>The significand of a finite non-zero Decimal128 value is a rational number.</p>
</emu-note>
<emu-note>
<p>The exponent _e_ of finite non-zero Decimal128 values is an integer satisfying 6144 β₯ _e_ β₯ -6176.</p>
</emu-note>
<p>A finite non-zero Decimal128 value is <dfn id="dfn-decimal128-normalized">normalized</dfn> if its exponent _e_ satisfies 6144 β₯ _e_ β₯ -6143. A finite non-zero Decimal128 value is <dfn id="dfn-decimal128-denormalized-">denormalized</dfn> if its exponent _e_ satisfies -6144 β₯ _e_ β₯ -6176.</p>
<p>For a proper discussion of rounding, we need to separate how rounding occurs with normalized compared with denormlized values. For a normalized Decimal128 value we define its <dfn>truncated exponent</dfn> as equal to its exponent. For zero or denormalized Decimal128 values we define the truncated exponent as the constant -6143. Given this, we define the <dfn>scaled significand</dfn> of a finite Decimal128 value as follows:</p>
<ul>
<li>The scaled significand of a zero Decimal128 value is 0.</li>
<li>The scaled significand of a non-zero Decimal128 value _v_ is _v_ Γ 10<sup>33</sup> β _te_</sup>, where _te_ is the truncated exponent of _x_.</li>
</ul>
<emu-note>
<p>The scaled significand of a finite Decimal128 value is always an integer whose absolute value is less than 10<sup>34</sup>.</p>
</emu-note>
</emu-intro>
<emu-clause id="sec-decimal-abstract-ops">
<h1>Abstract Operations</h1>
<emu-clause id="sec-decimal128-roundtodecimal128domain" type="abstract operation">
<h1>RoundToDecimal128Domain(
_v_: a mathematical value,
optional _roundingMode_: a Decimal128 rounding mode
): *+β*<sub>π»</sub>, *-β*<sub>π»</sub>, *+0*<sub>π»</sub>, *β0*<sub>π»</sub>, or a mathematical value
</h1>
<dl class="header">
<dt>description</dt>
<dd>It computes the closest approximation to a given mathematical value, rounded according to the given rounding mode, that is available within the limits of Decimal128.</dd>
</dl>
<emu-alg>
1. If _v_ = 0, return *+0*<sub>π»</sub>.
1. If v < 0, then
1. Let _reverseRoundingMode_ be _roundingMode_.
1. If _roundingMode_ is *"floor"*, set _reverseRoundingMode_ to *"ceil"*.
1. If _roundingMode_ is *"ceil"*, set _reverseRoundingMode_ to *"floor"*.
1. Let _d_ be RoundToDecimal128Domain(β_v_, _reverseRoundingMode_).
1. If _d_ is *+β*<sub>π»</sub>, return *ββ*<sub>π»</sub>.
1. If _d_ is *+0*<sub>π»</sub>, return *β0*<sub>π»</sub>.
1. Assert: _d_ is a mathematical value.
1. Return β_d_.
1. Let _e_ be the unique integer such that 10<sup>_e_</sup> β€ _v_ < 10<sup>_e_+1</sup>.
1. Let _te_ be _e_ β 33.
1. If _te_ < β6176, set _te_ to β6176.
1. Let _m_ be _v_ Γ 10<sup>β_te_</sup>.
1. Let _rounded_ be ApplyRoundingModeToPositive(_m_, _roundingMode_).
1. If _rounded_ = 10<sup>34</sup>, then
1. Set _te_ to _te_ + 1.
1. Set _rounded_ to 10<sup>33</sup>.
1. If _te_ > 6111, return *+β*<sub>π»</sub>.
1. If _rounded_ = 0, return *+0*<sub>π»</sub>.
1. Return _rounded_ Γ 10<sup>_te_</sup>.
</emu-alg>
<emu-clause id="sec-decimal128-applyroundingmodetopositive" type="abstract operation">
<h1>ApplyRoundingModeToPositive(
_m_: a positive mathematical value,
_roundingMode_: a Decimal128 rounding mode
): an integer
</h1>
<dl class="header">
<dt>description</dt>
<dd>It computes the closest integer approximation to a given positive mathematical value, rounded according to the given rounding mode.</dd>
</dl>
<emu-alg>
1. Let _mLow_ be floor(_m_).
1. Let _fraction_ be _m_ β _mLow_.
1. If _fraction_ = 0, return _mLow_.
1. Let _mHigh_ be _mLow_ + 1.
1. If _roundingMode_ is *"floor"* or *"trunc"*, return _mLow_.
1. If _roundingMode_ is *"ceil"*, return _mHigh_.
1. If _fraction_ < 0.5, return _mLow_.
1. If _fraction_ > 0.5, return _mHigh_.
1. If _roundingMode_ is *"halfExpand"*, return _mHigh_.
1. If _mLow_ is an even integer, return _mLow_.
1. Return _mHigh_.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-decimal128-abs" type="abstract operation">
<h1>
Decimal128Abs (
_argument_ : a Decimal128 value
): a Decimal128 value
</h1>
<dl class="header">
<dt>description</dt>
<dd>It computes the absolute value of a Decimal128 value</dd>
</dl>
<emu-alg>
1. If _argument_ is *NaN*<sub>π»</sub>, return *NaN*<sub>π»</sub>.
1. If _argument_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return *+β*<sub>π»</sub>.
1. If _argument_ is *+0*<sub>π»</sub> or *β0*<sub>π»</sub>, return *+0*<sub>π»</sub>.
1. Otherwise, return abs(_argument_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128-negate" type="abstract operation">
<h1>
Decimal128Negate (
_argument_ : a Decimal128 value
): a Decimal128 value
</h1>
<dl class="header">
<dt>description</dt>
<dd>It computes the negation of a Decimal128 value</dd>
</dl>
<emu-alg>
1. If _argument_ is *NaN*<sub>π»</sub>, return *NaN*<sub>π»</sub>.
1. If _argument_ is *+β*<sub>π»</sub>, return *-β*<sub>π»</sub>.
1. If _argument_ is *-β*<sub>π»</sub>, return *+β*<sub>π»</sub>.
1. If _argument_ is *+0*<sub>π»</sub>, return *β0*<sub>π»</sub>.
1. If _argument_ is *β0*<sub>π»</sub>, return *+0*<sub>π»</sub>.
1. Otherwise, return β_argument_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128-canonicalizedecimalstring" type="abstract operation">
<h1>
CanonicalizeDecimalString (
_digits_ : a String
): a String
</h1>
<dl class="header">
<dt>description</dt>
<dd>It removes trailing zeroes, if any, from _digits_, which is assumed to be a string of digits, possibily followed by a *"."* and a non-empty sequence of digits.</dd>
</dl>
<emu-alg>
1. If _digits_ does not contain the substring *"."*, return _digits_.
1. If the final code unit of _digits_ is not the code unit 0x0030 (DIGIT ZERO), return _digits_.
1. Let _lhs_ be the substring of _digits_ up to the first occurrence of the string *"."*.
1. Let _rhs_ be the substring of _digits_ starting at the first code point after the first occurrence of the string *"."*.
1. Let _noTrailingZeroes_ be the shortest substring of _rhs_ that does not terminate with a sequence of the code point 0x0030 (DIGIT ZERO).
1. If _noTrailingZeroes_ is *""*, return _lhs_.
1. Otherwise, return the concatenation of _lhs_, *"."*, and _noTrailingZeroes_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128-decimal128todecimalstring" type="abstract operation">
<h1>
Decimal128ToDecimalString (
_argument_ : a Decimal128 value
): a String
</h1>
<dl class="header">
<dt>description</dt>
<dd>It renders _argument_ as a string in decimal notation, regardless of how many decimal digits would be required.</dd>
</dl>
<emu-alg>
1. If _argument_ is *NaN*<sub>π»</sub>, return *"NaN"*.
1. If _argument_ is *+β*<sub>π»</sub>, return *"Infinity"*.
1. If _argument_ is *-β*<sub>π»</sub>, return *"-Infinity"*.
1. Let _sign_ be sign(_argument_).
1. If _sign_ = -1, let _prefix_ be *"-"*, else let _prefix_ be *""*.
1. Let _argument_ be Decimal128Abs(_argument_).
1. If _argument_ is *+0*<sub>π»</sub>, return the string concatenation of _prefix_ and *"0"*.
1. Let _q_ be the smallest integer such that _argument_ Γ 10<sup>β_q_</sup> is an integer.
1. Let _n_ be _argument_ Γ 10<sup>β_q_</sup>.
1. Assert: 0 < _n_ < 10<sup>34</sup>.
1. Let _digits_ be the unique decimal string representation of _n_ without leading zeroes.
1. Let _numDigits_ be the length of _digits_.
1. Let _integerPart_ be the substring of _digits_ from 0 to _numDigits_.
1. If _argument_ is an integer, then
1. Assert: _integerPart_ is not *""*.
1. Return _integerPart_.
1. If _integerPart_ is *""*, set _integerPart_ to *"0"*.
1. Let _nonIntegerPart_ be the substring of _digits_ from _numDigits_.
1. Let _renderedAbsoluteValue_ be the concatenation of _integerPart, *"."*, and _nonIntegerPart_.
1. Let _s_ be the concatenation of _prefix and _renderedAbsoluteValue_.
1. Return CanonicalizeDecimalString(_s_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128toexponentialstring" type="abstract operation">
<h1>
Decimal128ToExponentialString (
_argument_ : a Decimal128 value
): a String
</h1>
<dl class="header">
<dt>description</dt>
<dd>It renders _argument_ in exponential notation.</dd>
</dl>
<emu-alg>
1. If _argument_ is *NaN*<sub>π»</sub>, return *"NaN"*.
1. If _argument_ is *+β*<sub>π»</sub>, return *"Infinity"*.
1. If _argument_ is *-β*<sub>π»</sub>, return *"-Infinity"*.
1. Let _sign_ be sign(_argument_).
1. Let _argument_ be Decimal128Abs(_argument_).
1. If _sign_ = -1, let _prefix_ be *"-"*, else let _prefix_ be *""*.
1. If _argument_ is *+0*<sub>π»</sub> or *β0*<sub>π»</sub>, return the string concatenation of _prefix_ and *"0e+0".
1. Let _q_ be the smallest integer such that _argument_ Γ 10<sup>β_q_</sup> is an integer.
1. Let _n_ be _argument_ Γ 10<sup>β_q_</sup>.
1. Assert: 0 < _n_ < 10<sup>34</sup>.
1. Let _coefficientStr_ be the unique decimal string representation of _n_ without leading zeroes.
1. Let _e_ be the unique integer for which 1 β€ _n_ Γ 10<sup>_e_</sup> < 10.
1. Let _adjustedExp_ be -_e_.
1. Let _adjustedExpStr_ be the unique decimal string representation of _adjustedExp_ without leading zeroes.
1. Let _firstDigit_ be the substring of _coefficientStr_ from 0 to 1.
1. Let _remainingDigits_ be the substring of _coefficientStr_ starting at 1.
1. Return the concatenation of _prefix_, _firstDigit_, *"."*, _remainingDigits_, *"e"*, and _adjustedExpStr_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128-value-to-object" type="abstract operation">
<h1>
Decimal128ValueToObject (
_argument_ : a Decimal128 value
): a Decimal128 object
</h1>
<dl class="header">
<dt>description</dt>
<dd>It converts a Decimal128 value to a Decimal128 object.</dd>
</dl>
<emu-alg>
1. Let _O_ be ! OrdinaryCreateFromConstructor(%Decimal128%, *"%Decimal128.prototype%"*, Β« [[Decimal128Data]] Β»).
1. Set _O_.[[Decimal128Data]] to _argument_.
1. Return _O_.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-the-decimal-constructor">
<h1>The Decimal128 Constructor</h1>
<p>The Decimal128 constructor:</p>
<ul>
<li>is <dfn>%Decimal128%</dfn>.</li>
<li>is the initial value of the the *"Decimal128"* property of the global object.</li>
<li>creates and initializes a new Decimal128 object when called as a constructor</li>
<li>may be used as the value of an *extends* clause of a class definition. Subclass constructors that intend to inherit the specified Decimal128 behaviour must include a *super* call to the Decimal128 constructor to create and initialize the subclass instance with a [[Decimal128Data]] internal slot.</li>
</ul>
<emu-clause id="sec-the-decimal128-constructor-value">
<h1>Decimal128 ( _x_ )</h1>
<emu-alg>
1. If NewTarget is *undefined*, throw a *TypeError* exception.
1. Let _toParse_ be *undefined*.
1. If _x_ is a BigInt, set _toParse_ to BigInt::toString(_x_, 10).
1. Otherwise, if _x_ is a Number, set _toParse_ to ! Call(%Number.prototype.toExponential%, _x_, Β« Β»).
1. Otherwise, if _x_ is a String, set _toParse_ to _x_.
1. If _toParse_ is not a String, throw a *TypeError* exception.
1. Let _O_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%Decimal128.prototype%"*, Β« [[Decimal128Data]] Β»).
1. If _toParse_ is *"NaN"*, then
1. Set _O_.[[Decimal128Data]] to *NaN*<sub>π»</sub>.
1. Else,
1. Let _parseResult_ be ParseText(_toParse_, |StrDecimalLiteral|).
1. If _parseResult_ is a List of errors, throw a *SyntaxError* exception.
1. Let _decimalValue_ be ? StringDecimalValue of _parseResult_.
1. Set _O_.[[Decimal128Data]] to _decimalValue_.
1. Return _O_.
</emu-alg>
<emu-note>
<p>Given a Number argument, the constructor converts it to a String using the <emu-xref href="#sec-number.prototype.tostring">toString</emu-xref> method (with no arguments). In some cases, this may not be desited. In some use cases, given a Number, one may wish to call the Decimal128 constructor not with the number but rather with, for instance, the result of calling <emu-xref href="#sec-number.prototype.tofixed">toFixed</emu-xref> or <emu-xref href="#sec-number.prototype.toprecision">toPrecision</emu-xref> on the Number, thereby ensuring a certain level of precision that may get lost when using Numberβs toString.</p>
</emu-note>
<emu-clause id="sec-runtime-semantics-stringdecimalvalue" type="sdo">
<h1>Runtime Semantics: StringDecimalValue ( ): either a normal completion containing a Decimal128 value or a throw completion</h1>
<dl class="header">
</dl>
<emu-grammar>StrDecimalLiteral ::: `-` StrUnsignedDecimalLiteral</emu-grammar>
<emu-alg>
1. Let _a_ be ? StringDecimalValue of |StrUnsignedDecimalLiteral|.
1. If _a_ is *+β*<sub>π»</sub>, return *-β*<sub>π»</sub>.
1. Assert: _a_ is finite.
1. If _a_ is *+0*<sub>π»</sub>, return *β0*<sub>π»</sub>.
1. Return β_a_.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: `Infinity`</emu-grammar>
<emu-alg>
1. Return *+β*<sub>π»</sub>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: DecimalDigits `.` DecimalDigits? ExponentPart?</emu-grammar>
<emu-alg>
1. Let _a_ be MV of the first |DecimalDigits|.
1. If the second |DecimalDigits| is present, then
1. Let _b_ be MV of the second |DecimalDigits|.
1. Let _n_ be the number of code points in the second |DecimalDigits|.
1. Else,
1. Let _b_ be 0.
1. Let _n_ be 0.
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Return RoundToDecimal128Domain((_a_ + (_b_ Γ 10<sup>β_n_</sup>)) Γ 10<sup>_e_</sup>).
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: `.` DecimalDigits ExponentPart?</emu-grammar>
<emu-alg>
1. Let _b_ be MV of |DecimalDigits|.
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Let _n_ be the number of code points in |DecimalDigits|.
1. Let _newValue_ be _b_ Γ 10<sup>_e_ β _n_</sup>.
1. Return RoundToDecimal128Domain(_newValue_).
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPart?</emu-grammar>
<emu-alg>
1. Let _a_ be MV of |DecimalDigits|.
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|. Otherwise, let _e_ be 0.
1. Return RoundToDecimal128Domain(_a_ Γ 10<sup>_e_</sup>).
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="sec-decimal-prototype-properties">
<h1>Properties of the Decimal128 Prototype</h1>
<emu-clause id="sec-decimal128.prototype.isnan">
<h1>Decimal128.prototype.isNaN ( )</h1>
<p>This method returns a Boolean value indicating whether a Decimal128 object represents *NaN*<sub>π»</sub>.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Let _d_ be _O_.[[Decimal128Data]].
1. If _d_ is *NaN*<sub>π»</sub>, return *true*.
1. Otherwise, return *false*.
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.isfinite">
<h1>Decimal128.prototype.isFinite ( )</h1>
<p>This method returns a Boolean value indicating whether a Decimal128 object represents *+β*<sub>π»</sub> or *-β*<sub>π»</sub>.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Let _d_ be _O_.[[Decimal128Data]].
1. If _d_ is *NaN*<sub>π»</sub>, *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return *false*.
1. Otherwise, return *true*.
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.exponent">
<h1>Decimal128.prototype.exponent ( )</h1>
<p>This method returns a Number value represents the <emu-xref href="#dfn-decimal128-exponent">exponent</emu-xref>, which is the integer _n_ for which the current Decimal128 object, _v_, there exists a mathematical value _s_ such that _v_ = _s_ Γ 10<sup>_e_</sup> and 1 β€ abs(_s_) < 10. If the current Decimal128 object is infinite, it returns *+β*. If the current Decimal128 object is a zero, it returns *-β*.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Let _d_ be _O_.[[Decimal128Data]].
1. If _d_ is *NaN*<sub>π»</sub>, return *NaN*<sub>π½</sub>.
1. If _d_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return *+β*<sub>π½</sub>.
1. If _d_ is *+0*<sub>π»</sub> or *β0*<sub>π»</sub>, return *-β*<sub>π½</sub>.
1. Let _e_ be the unique integer for which there exists a mathematical value _s_ such that _d_ = _s_ Γ 10<sup>_e_</sup> and 1 β€ abs(_s_) < 10.
1. Return π½(_e_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.mantissa">
<h1>Decimal128.prototype.mantissa ( )</h1>
<p>This method returns a Decimal128 value representing the <emu-xref href="#dfn-decimal128-significand">significand</emu-xref> of the current Decimal128 object, which is the mathematical value _n_ for which the current Decimal128 object, _v_, there exists an integer _e_ such such that _v_ = _s_ Γ 10<sup>_e_</sup> and 1 β€ abs(_s_) < 10. IF the current Decimal128 object is a zero, it returns a zero.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Let _d_ be _O_.[[Decimal128Data]].
1. If _d_ is *NaN*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π½</sub>).
1. If _d_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return Decimal128ValueToObject(*+β*<sub>π½</sub>).
1. If _d_ is *+0*<sub>π»</sub>, return Decimal128ValueToObject(*+0*<sub>π»</sub>).
1. If _d_ is *β0*<sub>π»</sub>, return Decimal128ValueToObject(*-0*<sub>π»</sub>).
1. Let _e_ be the truncated exponent of _d_.
1. Let _s_ be the unique mathematical value such that _d_ = _s_ Γ 10<sup>_e_</sup> and 1 β€ abs(_s_) < 10.
1. Return Decimal128ValueToObject(_s_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.abs">
<h1>Decimal128.prototype.abs ( )</h1>
<p>This method computes the absolute value of a Decimal128 object.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Let _d_ be _O_.[[Decimal128Data]].
1. Return Decimal128ValueToObject(Decimal128Abs(_d_)).
</emu-alg>
<emu-note>
<p>This operation follows the specification in Section 5.5.1 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.negate">
<h1>Decimal128.prototype.negate ( )</h1>
<p>This method inverts the sign of a Decimal128 object.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Let _d_ be _O_.[[Decimal128Data]].
1. Return Decimal128ValueToObject(Decimal128Negate(_d_)).
</emu-alg>
<emu-note>
<p>This operation follows the specification in Section 5.5.1 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.add">
<h1>Decimal128.prototype.add ( _x_ )</h1>
<p>This method computes the addition of a Decimal128 object with another one. The computation proceeds as though infinite precision and unbounded range were available, rounding, if necessary.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ or _d2_ is *NaN*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d1_ is *+β*<sub>π»</sub> or _d2_ is *+β*<sub>π»</sub>, then
1. If _d1_ is *-β*<sub>π»</sub> or _d2_ is *-β*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. Return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. If _d1_ is *-β*<sub>π»</sub> or _d2_ is *-β*<sub>π»</sub>, then
1. Assert: _d1_ is not *+β*<sub>π»</sub> and _d2_ is not *+β*<sub>π»</sub>.
1. Return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. If _d1_ is *β0*<sub>π»</sub>, return Decimal128ValueToObject(_d2_).
1. If _d2_ is *β0*<sub>π»</sub>, return Decimal128ValueToObject(_d1_).
1. If _d1_ is *+0*<sub>π»</sub>, set _d1_ to 0.
1. If _d2_ is *+0*<sub>π»</sub>, set _d2_ to 0.
1. Let _sum_ be _d1_ + _d2_.
1. Return Decimal128ValueToObject(RoundToDecimal128Domain(_sum_)).
</emu-alg>
<emu-note>
<p>This operation follows the specification in Section 5.4.1 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.subtract">
<h1>Decimal128.prototype.subtract ( _x_ )</h1>
<p>This method computes subtracts the given Decimal128 object from the current one. The computation proceeds as though infinite precision and unbounded range were available, rounding, if necessary.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ or _d2_ is *NaN*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d1_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, then
1. If _d2_ is _d1_, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. Return Decimal128ValueToObject(_d1_).
1. If _d2_ is *+β*<sub>π»</sub>, return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. If _d2_ is *-β*<sub>π»</sub>, return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. If _d1_ is *β0*<sub>π»</sub> and _d2_ is *+0*<sub>π»</sub>, return Decimal128ValueToObject((*β0*<sub>π»</sub>)).
1. If _d1_ is *+0*<sub>π»</sub> or *β0*<sub>π»</sub>, set _d1_ to 0.
1. If _d2_ is *+0*<sub>π»</sub> or *β0*<sub>π»</sub>, set _d2_ to 0.
1. Let _difference_ be _d1_ β _d2_.
1. Return Decimal128ValueToObject(RoundToDecimal128Domain(_difference_)).
</emu-alg>
<emu-note>
<p>This operation follows the specification in Section 5.4.1 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.multiply">
<h1>Decimal128.prototype.multiply ( _x_ )</h1>
<p>This method computes multiplies the current Decimal128 object by another one. The computation proceeds as though infinite precision and unbounded range were available, rounding, if necessary.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ or _d2_ is *NaN*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d1_ or _d2_ is *+β*<sub>π»</sub>, then
1. If _d1_ or _d2_ is a zero Decimal128 value, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If sign(_d1_) = -1 or sign(_d2_) = -1, return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. Return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. If _d1_ or _d2_ is *-β*<sub>π»</sub>, then
1. If _d1_ or _d2_ is a zero Decimal128 value, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If sign(_d1_) = -1 and sign(_d2_) = -1, return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. Return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. If _d1_ or _d2_ is *+0*<sub>π»</sub>, then
1. If sign(_d1_) = -1 or sign(_d2_) = -1, return Decimal128ValueToObject(*β0*<sub>π»</sub>).
1. Return Decimal128ValueToObject(*+0*<sub>π»</sub>).
1. If _d1_ or _d2_ is *β0*<sub>π»</sub>, then
1. If sign(_d1_) = -1 and sign(_d2_) = -1, return Decimal128ValueToObject(*+0*<sub>π»</sub>_).
1. Return Decimal128ValueToObject(*β0*<sub>π»</sub>).
1. Let _product_ be _d1_ Γ _d2_.
1. Assert: _product_ β 0.
1. Return Decimal128ValueToObject(RoundToDecimal128Domain(_product_)).
</emu-alg>
<emu-note>
<p>This operation follows the specification in Section 5.4.1 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.divide">
<h1>Decimal128.prototype.divide ( _x_ )</h1>
<p>This method computes divides the current Decimal128 object by another one. The computation proceeds as though infinite precision and unbounded range were available, rounding, if necessary.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ or _d2_ is *NaN*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d1_ is *+β*<sub>π»</sub>, then
1. If _d2_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If sign(_d2_) = -1, return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. If _d1_ is *-β*<sub>π»</sub>, then
1. If _d2_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If sign(_d2_) = -1, return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. If _d2_ is *+β*<sub>π»</sub>, then
1. If sign(_d1_) = -1, return Decimal128ValueToObject(*β0*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*+0*<sub>π»</sub>).
1. If _d2_ is *-β*<sub>π»</sub>, then
1. If sign(_d1_) = -1, return Decimal128ValueToObject(*+0*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*β0*<sub>π»</sub>).
1. If _d2_ is *+0*<sub>π»</sub>, then
1. If _d1_ is *+0*<sub>π»</sub> or *-0*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d1_ < 0, return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. If _d2_ is *β0*<sub>π»</sub>, then
1. If _d1_ is *+0*<sub>π»</sub> or *-0*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d1_ < 0, return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. If _d1_ is *+0*<sub>π»</sub>, then
1. If _d2_ < 0, return Decimal128ValueToObject(*β0*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*+0*<sub>π»</sub>).
1. If _d1_ is *β0*<sub>π»</sub>, then
1. If _d2_ < 0, return Decimal128ValueToObject(*+0*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*β0*<sub>π»</sub>).
1. Let _quotient_ be _d1_ / _d2_.
1. Return Decimal128ValueToObject(RoundToDecimal128Domain(_quotient_)).
</emu-alg>
<emu-note>
<p>This operation follows the specification in Section 5.4.1 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.remainder">
<h1>Decimal128.prototype.remainder ( _x_ )</h1>
<p>This method computes the remainder upon dividing the current Decimal128 object by another one. The computation proceeds as though infinite precision and unbounded range were available, rounding, if necessary.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ or _d2_ is *NaN*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d1_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d2_ is *-β*<sub>π»</sub> or *-β*<sub>π»</sub>, return Decimal128ValueToObject(_d1_).
1. If _d2_ is *+0*<sub>π»</sub> or *β0*<sub>π»</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _d1_ is *+0*<sub>π»</sub> or *β0*<sub>π»</sub>, return Decimal128ValueToObject(_d1_).
1. Assert: _d2_ β 0.
1. Let _quotient_ be _d1_ / _d2_.
1. Let _q_ be truncate(_quotient_).
1. Let _r_ be _d1_ - (_d2_ Γ _q_).
1. If _r_ = 0, and _d1_ < 0, return Decimal128ValueToObject(*β0*<sub>π½</sub>).
1. Otherwise, return Decimal128ValueToObject(_r_).
</emu-alg>
<emu-note>
<p>The remainder operation specified here deviates from the <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref> remainder operation (defined there in Section 5.3.1). We follow the <emu-xref href="#sec-numeric-types-number-remainder">the remainder operation for Number</emu-xref> rather than IEEE 754, which specifies that, for example, the remainder 46 and 10 is -4 rather than 6.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.compare">
<h1>Decimal128.prototype.compare ( _x_ )</h1>
<p>This method returns one of the four Number values *-1*<sub>π½</sub>, *+0*<sub>π½</sub>, *1*<sub>π½</sub>, and *NaN*<sub>π½</sub>. It compares the mathematical value of the current Decimal128 object with that of another Decimal128 object.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ is *NaN*<sub>π»</sub>, return *NaN*<sub>π½</sub>.
1. If _d2_ is *NaN*<sub>π»</sub>, return *NaN*<sub>π½</sub>.
1. If _d1_ is *+β*<sub>π»</sub>, then
1. If _d2_ is *+β*<sub>π»</sub>, return *+0*<sub>π½</sub>.
1. Return *1*<sub>π½</sub>.
1. If _d1_ is *-β*<sub>π»</sub>, then
1. If _d2_ is *-β*<sub>π»</sub>, return *+0*<sub>π½</sub>.
1. Return *-1*<sub>π½</sub>.
1. If _d2_ is *+β*<sub>π»</sub>, return *-1*<sub>π½</sub>.
1. If _d2_ is *-β*<sub>π»</sub>, return *1*<sub>π½</sub>.
1. If MV(_d1_) < MV(_d2_), return *-1*<sub>π½</sub>.
1. If MV(_d2_) < MV(_d1_), return *1*<sub>π½</sub>.
1. Otherwise, return *+0*<sub>π½</sub>.
</emu-alg>
<emu-note>
<p>This operation combines the <code>compareQuietEqual</code>, <code>compareQuietLess</code> operations in Section 5.6.1 (and explained in Section 5.11) of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.equals">
<h1>Decimal128.prototype.equals ( _x_ )</h1>
<p>This method returns either *true*, *false*, or *undefined* according as the current Decimal128 object has the same mathematical value as the given Decimal128 object. The value *undefined* is returned if the current Decimal128 object or the argument is a NaN.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ is *NaN*<sub>π»</sub>, return *undefined*.
1. If _d2_ is *NaN*<sub>π»</sub>, return *undefined*.
1. If _d1_ is *+β*<sub>π»</sub>, then
1. If _d2_ is *+β*<sub>π»</sub>, return *true*.
1. Otherwise, return *false*.
1. If _d1_ is *-β*<sub>π»</sub>, then
1. If _d2_ is *-β*<sub>π»</sub>, return *true*.
1. Otherwise, return *false*.
1. If _d2_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return *false*.
1. If MV(_d1_) = MV(_d2_), return *true*.
1. Otherwise, return *false*.
</emu-alg>
<emu-note>
<p>This operation corresponds to the <code>compareQuietEqual</code> operation in Section 5.6.1 (and explained in Section 5.11) of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.notequals">
<h1>Decimal128.prototype.notEquals ( _x_ )</h1>
<p>This method returns either *true*, *false*, or *undefined* according as the current Decimal128 object has a different mathematical value as the given Decimal128 object. The value *undefined* is returned if the current Decimal128 object or the argument is a NaN.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ is *NaN*<sub>π»</sub>, return *undefined*.
1. If _d2_ is *NaN*<sub>π»</sub>, return *undefined*.
1. If _d1_ is *+β*<sub>π»</sub>, then
1. If _d2_ is *+β*<sub>π»</sub>, return *false*.
1. Otherwise, return *true*.
1. If _d1_ is *-β*<sub>π»</sub>, then
1. If _d2_ is *-β*<sub>π»</sub>, return *false*.
1. Otherwise, return *true*.
1. If _d2_ is *+β*<sub>π»</sub> or *-β*<sub>π»</sub>, return *true*.
1. If MV(_d1_) β MV(_d2_), return *true*.
1. Otherwise, return *false*.
</emu-alg>
<emu-note>
<p>This operation corresponds to the <code>compareQuietNotEqual</code> operation in Section 5.6.1 (and explained in Section 5.11) of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.lessthan">
<h1>Decimal128.prototype.lessThan ( _x_ )</h1>
<p>This method returns either *true*, *false* according as the current Decimal128 object has the same mathematical value as the given Decimal128 object. The value *false* is returned if the current Decimal128 object or the argument is a NaN.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ is *NaN*<sub>π»</sub>, return *false*.
1. If _d2_ is *NaN*<sub>π»</sub>, return *false*.
1. If _d1_ is *+β*<sub>π»</sub>, return *false*.
1. If _d1_ is *-β*<sub>π»</sub>, then
1. If _d2_ is *-β*<sub>π»</sub>, return *false*.
1. Otherwise, return *true*.
1. If _d2_ is *+β*<sub>π»</sub>, return *true*.
1. If _d2_ is *-β*<sub>π»</sub>, return *false*.
1. If MV(_d1_) < MV(_d2_), return *true*.
1. Otherwise, return *false*.
</emu-alg>
<emu-note>
<p>This operation corresponds to the <code>compareQuietEqual</code> operation in Section 5.6.1 (and explained in Section 5.11) of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.lessthanorequal">
<h1>Decimal128.prototype.lessThanOrEqual ( _x_ )</h1>
<p>This method returns either *true*, *false*, or *undefined* according as the current Decimal128 object has the same or smaller mathematical value as the given Decimal128 object. The value *false* is returned if the current Decimal128 object or the argument is a NaN.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ is *NaN*<sub>π»</sub>, return *false*.
1. If _d2_ is *NaN*<sub>π»</sub>, return *false*.
1. If _d1_ is *+β*<sub>π»</sub>, then
1. If _d2_ is *+β*<sub>π»</sub>, return *true*.
1. Otherwise, return *false*.
1. If _d1_ is *-β*<sub>π»</sub>, return *true*.
1. If _d2_ is *+β*<sub>π»</sub>, return *true*.
1. If _d2_ is *-β*<sub>π»</sub>, return *false*.
1. If MV(_d1_) β€ MV(_d2_), return *true*.
1. Otherwise, return *false*.
</emu-alg>
<emu-note>
<p>This operation corresponds to the <code>compareQuietLessEqual</code> operation in Section 5.6.1 (and explained in Section 5.11) of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.greaterthan">
<h1>Decimal128.prototype.greaterThan ( _x_ )</h1>
<p>This method returns either *true*, *false* according as the current Decimal128 object has a greater mathematical value as the given Decimal128 object. The value *false* is returned if either the current Decimal128 object or the argument is a NaN.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ is *NaN*<sub>π»</sub>, return *false*.
1. If _d2_ is *NaN*<sub>π»</sub>, return *false*.
1. If _d1_ is *+β*<sub>π»</sub>, then
1. If _d2_ is *+β*<sub>π»</sub>, return *false*.
1. Otherwise, return *true*.
1. If _d1_ is *-β*<sub>π»</sub>, return *false*.
1. If _d2_ is *+β*<sub>π»</sub>, return *false*.
1. If _d2_ is *-β*<sub>π»</sub>, return *true*.
1. If MV(_d1_) > MV(_d2_), return *true*.
1. Otherwise, return *false*.
</emu-alg>
<emu-note>
<p>This operation corresponds to the <code>compareQuietGreater</code> operation in Section 5.6.1 (and explained in Section 5.11) of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.greaterthanorequal">
<h1>Decimal128.prototype.greaterThanOrEqual ( _x_ )</h1>
<p>This method returns either *true*, *false** according as the current Decimal128 object has a greater or equal mathematical value as the given Decimal128 object. The value *false* is returned if the current Decimal128 object or the argument is a NaN.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Perform ? RequireInternalSlot(_x_, [[Decimal128Data]]).
1. Let _d1_ be _O_.[[Decimal128Data]].
1. Let _d2_ be _x_.[[Decimal128Data]].
1. If _d1_ is *NaN*<sub>π»</sub>, return *false*.
1. If _d2_ is *NaN*<sub>π»</sub>, return *false*.
1. If _d1_ is *+β*<sub>π»</sub>, return *true*.
1. If _d1_ is *-β*<sub>π»</sub>, return *false*.
1. If _d2_ is *+β*<sub>π»</sub>, return *false*.
1. If _d2_ is *-β*<sub>π»</sub>, return *true*.
1. If MV(_d1_) β₯ MV(_d2_), return *true*.
1. Otherwise, return *false*.
</emu-alg>
<emu-note>
<p>This operation corresponds to the <code>compareQuietGreaterEqual</code> operation in Section 5.6.1 (and explained in Section 5.11) of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal-method-round">
<h1>Decimal128.prototype.round ( _numFractionalDigits_ [ , _roundingMode_ ] )</h1>
<p>This method rounds the current Decimal128 object according to the specified rounding mode, which, if omitted, is <emu-xref href="#dfn-decimal128-default-rounding-mode">the default rounding mode</emu-xref>, with rounding taking place only after _numFractionalDigits_ non-integer digits, which must be a non-negative integer Number.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. If _numFractionalDigits_ is not a Number, throw a *TypeError* exception.
1. If _numFractionalDigits_ is not an integer, throw a *RangeError* exception.
1. If _roundingMode_ is neither *undefined* nor a String, throw a *TypeError* exception.
1. If _roundingMode_ is undefined, set _roundingMode_ to <emu-xref href="#dfn-decimal128-default-rounding-mode">the default rounding mode</emu-xref>.
1. If _roundingMode_ is not a rounding mode, throw a *RangeError* exception.
1. Let _d_ be _O_.[[Decimal128Data]].
1. If _d_ is one of Β« *NaN*<sub>π»</sub>, *+β*<sub>π»</sub>, *-β*<sub>π»</sub> Β» return Decimal128ValueToObject(_d_).
1. If _d_ is *+0*<sub>π»</sub> or *β0*<sub>π»</sub>, return Decimal128ValueToObject(_d_).
1. Let _sign_ be sign(_d_).
1. Let _scaledV_ be _d_ Γ 10<sup>β(_numFractionalDigits_)</sup>.
1. If _sign_ = -1, then
1. Set _scaledV_ to β_scaledV_.
1. If _roundingMode_ is *"floor"*, set _roundingMode_ to *"ceil"*.
1. Else if _roundingMode_ is *"ceil"*, set _roundingMode_ to *"floor"*.
1. Let _roundedScaledV_ be ApplyRoundingModeToPositive(_scaledV_, _roundingMode_).
1. If _sign_ = -1, set _roundedScaledV_ to β_roundedScaledV_.
1. Let _rescaledRoundedV_ be _roundedScaledV_ Γ 10<sup>β_numFractionalDigits_</sup>.
1. Return Decimal128ValueToObject(RoundToDecimal128Domain(_rescaledRoundedV_, _roundingMode_)).
</emu-alg>
<emu-note>
<p>This operation follows the specification of the rounding mode attributes discussed in Section 4.3 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal-method-scale10">
<h1>Decimal128.prototype.scale10 ( _n_ )</h1>
<p>This method multiplies the current Decimal128 object by 10 raised to the given power.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. If _n_ is not a Number, throw a *TypeError* exception.
1. If _n_ is not one of Β« *NaN*<sub>π½</sub>, *+β*<sub>π½</sub>, *-β*<sub>π½</sub> Β», then
1. If β(_n_) is not an integer, throw a *RangeError* exception.
1. Let _d_ be _O_.[[Decimal128Data]].
1. If _d_ is *NaN*<sub>π»</sub>, *+β*<sub>π»</sub>, or *-β*<sub>π»</sub>, return Decimal128ValueToObject(_d_).
1. If _d_ is either *+0*<sub>π»</sub> nor *β0*<sub>π»</sub>, then
1. If _n_ is *NaN*<sub>π½</sub>, return Decimal128ValueToObject(_d_).
1. If _n_ is *+β*<sub>π½</sub>, return Decimal128ValueToObject(_d_).
1. If _n_ is *-β*<sub>π½</sub>, return Decimal128ValueToObject(_d_).
1. Otherwise, return Decimal128ValueToObject(_d_).
1. If _n_ is *NaN*<sub>π½</sub>, return Decimal128ValueToObject(*NaN*<sub>π»</sub>).
1. If _n_ is *+β*<sub>π½</sub>, then
1. If _d_ > 0, return Decimal128ValueToObject(*+β*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*-β*<sub>π»</sub>).
1. If _n_ is *-β*<sub>π½</sub>, then
1. If _d_ > 0, return Decimal128ValueToObject(*+0*<sub>π»</sub>).
1. Otherwise, return Decimal128ValueToObject(*β0*<sub>π»</sub>).
1. Let _w_ be v Γ 10<sup>β(_n_)</sup>.
1. Return Decimal128ValueToObject(RoundToDecimal128Domain(_w_)).
</emu-alg>
<emu-note>
<p>This operation follows the specification of the <code>scaleB</code> operation discussed in Section 5.3.3 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.tostring">
<h1>Decimal128.prototype.toString ( [ _options_ ] )</h1>
<p>This method generates a String representation of the current Decimal128 object, in decimal format. Its behaviour is similar to that of Numberβs <emu-xref href="#sec-number.prototype.tostring">toString</emu-xref> by rendering the decimal in decimal notation, but will use exponential notation if the the magnitude of the number is less than 10<sup>-6</sup> or greater than 10<sup>34</sup>.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. If _options_ is not *undefined*, then
1. If _options_ is not an Object, throw a *TypeError* exception.
1. Let _d_ be _O_.[[Decimal128Data]].
1. If _d_ is *NaN*<sub>π»</sub>, return "NaN".
1. If _d_ is *+β*<sub>π»</sub>, return "Infinity".
1. If _d_ is *-β*<sub>π»</sub>, return "-Infinity".
1. If _d_ is *+0*<sub>π»</sub>, return *"0"*.
1. If _d_ is *β0*<sub>π»</sub>, return *"-0"*.
1. If abs(_d_) < 10<sup>-6</sup> or abs(_d_) β₯ 10<sup>34</sup>, return return Decimal128ToExponentialString(_O_).
1. Otherwise, return Decimal128ToDecimalString(_O_).
</emu-alg>
<emu-note>
<p>This operation follows the specification of the conversion of IEEE 754-2019 Decimal128 values to strings (external character sequences) discussed in Section 5.12 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.tolocalestring">
<h1>Decimal128.prototype.toLocaleString ( [ _reserved1_ [ , _reserved2_ ] ] )</h1>
<p>An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:</p>
<p>This method produces a String value that represents this Decimal128 object formatted according to the conventions of the host environmentβs current locale. This method is implementation-defined, and it is permissible, but not encouraged, for it to return the same thing as <emu-xref href="#sec-decimal128.prototype.tostring">`toString`</emu-xref>.</p>
<p>The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.</p>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.toexponential">
<h1>Decimal128.prototype.toExponential ( [ _options_ ] )</h1>
<p>This method generates a String representation of the current Decimal128 object, in exponential format (e.g., *"123e-4"*).</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. If _options_ is not *undefined*, then
1. If _options_ is not an Object, throw a *TypeError* exception.
1. Return Decimal128ToExponentialString(_O_).
</emu-alg>
<emu-note>
<p>This operation follows the specification of the conversion of IEEE 754-2019 Decimal128 values to strings (external character sequences) discussed in Section 5.12 of <emu-xref href="#sec-bibliography">IEEE 754-2019</emu-xref>.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-decimal128.prototype.tofixed">
<h1>Decimal128.prototype.toFixed ( [ _options_ ] )</h1>
<p>This method generates a String representation of the current Decimal128 object, in decimal format, with a specified number of digits after the decimal point.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[Decimal128Data]]).
1. Let _numDigits_ be *+0*<sub>π½</sub>.
1. Let _roundingMode_ be *undefined*.
1. If _options_ is not *undefined*, then
1. If _options_ is not an Object, throw a *TypeError* exception.
1. Set _numDigits_ to ? Get(_options_, *"digits"*).
1. Set _roundingMode_ to ? Get(_options_, *"roundingMode"*).
1. If _numDigits_ is not a Number, throw a *TypeError* exception.
1. If _numDigits_ is *NaN*<sub>π½</sub>, *+β*<sub>π½</sub>, or *-β*<sub>π½</sub>, throw a *RangeError* exception.
1. Set _numDigits_ to β(_numDigits_).
1. If _numDigits_ < 0, throw a *RangeError* exception.
1. If _numDigits_ is not an integer, throw a *RangeError* exception.
1. If _roundingMode_ is *undefined*, set _roundingMode_ to *"halfEven"*.
1. Else if _roundingMode_ is not a String, throw a *TypeError* exception.
1. Else if _roundingMode_ is not a <emu-xref href="#dfn-decimal128-rounding-mode">Decimal128 rounding mode</emu-xref>, throw a *RangeError* exception.
1. Let _d_ be _O_.[[Decimal128Data]].
1. If _d_ is *NaN*<sub>π»</sub>, return *"NaN"*.
1. If _d_ is *+β*<sub>π»</sub>, return *"Infintiy"*.
1. If _d_ is *-β*<sub>π»</sub>, return *"-Infintiy"*.
1. If sign(_d_) = 1, let _signPrefix_ be *""*, else let _signPrefix_ be *"-"*.
1. If _d_ is *+0*<sub>π»</sub> or *-0*<sub>π»</sub>, then
1. If _numDigits_ = 0, then
1. Return the concatenation of _signPrefix_ and *"0"*.
1. Otherwise:
1. Let _trailingZeroes_ be *"0"* repeated _numDigits_ times.
1. Return the concatenation of _signPrefix, *"0"*, *"."*, and _trailingZeroes_.
1. Set _d_ to abs(_d_).
1. Let _scaledV_ be _d_ Γ 10<sup>_numDigits_</sup>.
1. Let _roundedScaledV_ be ApplyRoundingModeToPositive(_scaledV_, _roundingMode_).
1. Let _s_ be the unique decimal string representation of _roundedScaledV_ without leading zeroes.
1. Let _integerDigits_ be _s_.
1. Let _nonIntegerDigits_ be *""*.
1. If _s_ contains an occurrence of *"."*, then
1. Let _i_ be the index of the first occurrence of *"."* in _s_.
1. Set _integerDigits_ to the substring of _s_ from 0 to _i_.
1. Set _nonIntegerDigits_ to the substring of _s_ from _i_ + 1.