-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathspec.emu
More file actions
854 lines (826 loc) · 50 KB
/
Copy pathspec.emu
File metadata and controls
854 lines (826 loc) · 50 KB
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
<!DOCTYPE html>
<meta charset="utf8">
<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: Keep trailing zeros in Intl.NumberFormat and Intl.PluralRules
stage: 3
contributors: Eemeli Aro
location: https://tc39.es/proposal-intl-keep-trailing-zeros/
</pre>
<emu-clause id="numberformat-objects" number="16">
<h1>NumberFormat Objects</h1>
<emu-clause id="sec-intl-numberformat-constructor">
<h1>The Intl.NumberFormat Constructor</h1>
<emu-clause id="sec-setnumberformatdigitoptions" oldids="sec-setnfdigitoptions" type="abstract operation" number="2">
<h1>
SetNumberFormatDigitOptions (
_intlObj_: an Object,
_options_: an Object,
_mnfdDefault_: an integer,
_mxfdDefault_: an integer,
_notation_: a String,
): either a normal completion containing ~unused~ or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It populates the internal slots of _intlObj_ that affect locale-independent number rounding (see <emu-xref href="#sec-formatnumerictostring"></emu-xref>).</dd>
</dl>
<emu-alg>
1. Let _mnid_ be ? GetNumberOption(_options_, *"minimumIntegerDigits,"*, 1, 21, 1).
1. Let _mnfd_ be ? Get(_options_, *"minimumFractionDigits"*).
1. Let _mxfd_ be ? Get(_options_, *"maximumFractionDigits"*).
1. Let _mnsd_ be ? Get(_options_, *"minimumSignificantDigits"*).
1. Let _mxsd_ be ? Get(_options_, *"maximumSignificantDigits"*).
1. Set _intlObj_.[[MinimumIntegerDigits]] to _mnid_.
1. Let _roundingIncrement_ be ? GetNumberOption(_options_, *"roundingIncrement"*, 1, 5000, 1).
1. If _roundingIncrement_ is not in « 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 », throw a *RangeError* exception.
1. Let _roundingMode_ be ? GetOption(_options_, *"roundingMode"*, ~string~, « *"ceil"*, *"floor"*, *"expand"*, *"trunc"*, *"halfCeil"*, *"halfFloor"*, *"halfExpand"*, *"halfTrunc"*, *"halfEven"* », *"halfExpand"*).
1. Let _roundingPriority_ be ? GetOption(_options_, *"roundingPriority"*, ~string~, « *"auto"*, *"morePrecision"*, *"lessPrecision"* », *"auto"*).
1. Let _trailingZeroDisplay_ be ? GetOption(_options_, *"trailingZeroDisplay"*, ~string~, « *"auto"*, *"stripIfInteger"*<ins>, *"stripToMinimum"*</ins> », *"auto"*).
1. NOTE: All fields required by SetNumberFormatDigitOptions have now been read from _options_. The remainder of this AO interprets the options and may throw exceptions.
1. If _roundingIncrement_ is not 1, set _mxfdDefault_ to _mnfdDefault_.
1. Set _intlObj_.[[RoundingIncrement]] to _roundingIncrement_.
1. Set _intlObj_.[[RoundingMode]] to _roundingMode_.
1. Set _intlObj_.[[TrailingZeroDisplay]] to _trailingZeroDisplay_.
1. If _mnsd_ is *undefined* and _mxsd_ is *undefined*, let _hasSd_ be *false*. Otherwise, let _hasSd_ be *true*.
1. If _mnfd_ is *undefined* and _mxfd_ is *undefined*, let _hasFd_ be *false*. Otherwise, let _hasFd_ be *true*.
1. Let _needSd_ be *true*.
1. Let _needFd_ be *true*.
1. If _roundingPriority_ is *"auto"*, then
1. Set _needSd_ to _hasSd_.
1. If _needSd_ is *true*, or _hasFd_ is *false* and _notation_ is *"compact"*, then
1. Set _needFd_ to *false*.
1. If _needSd_ is *true*, then
1. If _hasSd_ is *true*, then
1. Set _intlObj_.[[MinimumSignificantDigits]] to ? DefaultNumberOption(_mnsd_, 1, 21, 1).
1. Set _intlObj_.[[MaximumSignificantDigits]] to ? DefaultNumberOption(_mxsd_, _intlObj_.[[MinimumSignificantDigits]], 21, 21).
1. Else,
1. Set _intlObj_.[[MinimumSignificantDigits]] to 1.
1. Set _intlObj_.[[MaximumSignificantDigits]] to 21.
1. If _needFd_ is *true*, then
1. If _hasFd_ is *true*, then
1. Set _mnfd_ to ? DefaultNumberOption(_mnfd_, 0, 100, *undefined*).
1. Set _mxfd_ to ? DefaultNumberOption(_mxfd_, 0, 100, *undefined*).
1. If _mnfd_ is *undefined*, set _mnfd_ to min(_mnfdDefault_, _mxfd_).
1. Else if _mxfd_ is *undefined*, set _mxfd_ to max(_mxfdDefault_, _mnfd_).
1. Else if _mnfd_ is greater than _mxfd_, throw a *RangeError* exception.
1. Set _intlObj_.[[MinimumFractionDigits]] to _mnfd_.
1. Set _intlObj_.[[MaximumFractionDigits]] to _mxfd_.
1. Else,
1. Set _intlObj_.[[MinimumFractionDigits]] to _mnfdDefault_.
1. Set _intlObj_.[[MaximumFractionDigits]] to _mxfdDefault_.
1. If _needSd_ is *false* and _needFd_ is *false*, then
1. Set _intlObj_.[[MinimumFractionDigits]] to 0.
1. Set _intlObj_.[[MaximumFractionDigits]] to 0.
1. Set _intlObj_.[[MinimumSignificantDigits]] to 1.
1. Set _intlObj_.[[MaximumSignificantDigits]] to 2.
1. Set _intlObj_.[[RoundingType]] to ~more-precision~.
1. Set _intlObj_.[[ComputedRoundingPriority]] to *"morePrecision"*.
1. Else if _roundingPriority_ is *"morePrecision"*, then
1. Set _intlObj_.[[RoundingType]] to ~more-precision~.
1. Set _intlObj_.[[ComputedRoundingPriority]] to *"morePrecision"*.
1. Else if _roundingPriority_ is *"lessPrecision"*, then
1. Set _intlObj_.[[RoundingType]] to ~less-precision~.
1. Set _intlObj_.[[ComputedRoundingPriority]] to *"lessPrecision"*.
1. Else if _hasSd_ is *true*, then
1. Set _intlObj_.[[RoundingType]] to ~significant-digits~.
1. Set _intlObj_.[[ComputedRoundingPriority]] to *"auto"*.
1. Else,
1. Set _intlObj_.[[RoundingType]] to ~fraction-digits~.
1. Set _intlObj_.[[ComputedRoundingPriority]] to *"auto"*.
1. If _roundingIncrement_ is not 1, then
1. If _intlObj_.[[RoundingType]] is not ~fraction-digits~, throw a *TypeError* exception.
1. If _intlObj_.[[MaximumFractionDigits]] is not _intlObj_.[[MinimumFractionDigits]], throw a *RangeError* exception.
1. Return ~unused~.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-intl-numberformat-instances" number="4">
<h1>Properties of Intl.NumberFormat Instances</h1>
<ul>
<li>...</li>
<li>[[TrailingZeroDisplay]] is one of the String values *"auto"*<del> or</del><ins>,</ins> *"stripIfInteger"*<ins>, or *"stripToMinimum"*</ins>, indicating whether to <ins>retain them when possible,</ins> strip trailing zeros if the formatted number is an integer (i.e., has no non-zero fraction digit)<ins>, or strip them at positions beyond the minimum count of fraction or significant digits, as applicable</ins>.</li>
</ul>
</emu-clause>
<emu-clause id="sec-numberformat-abstracts">
<h1>Abstract Operations for NumberFormat Objects</h1>
<ins class="block">
<emu-clause id="sec-intl-mv-records" oldids="intl-mathematical-value">
<h1><ins>Intl MV Records</ins></h1>
<p>An <dfn variants="Intl MV Records">Intl MV Record</dfn> is a Record value used to encapsulate a mathematical value together with additional information.</p>
<p>Intl MV Records have the fields listed in <emu-xref href="#table-intl-mv-record-fields"></emu-xref>.</p>
<emu-table id="table-intl-mv-record-fields" caption="Intl MV Record Fields">
<table>
<thead>
<tr>
<th>
Field Name
</th>
<th>
Value
</th>
<th>
Meaning
</th>
</tr>
</thead>
<tr>
<td>
[[Value]]
</td>
<td>
a mathematical value or one of ~positive-infinity~, ~negative-infinity~, ~not-a-number~, or ~negative-zero~
</td>
<td>
The value being formatted or selected on.
</td>
</tr>
<tr>
<td>
[[StringDigitCount]]
</td>
<td>
a non-negative integer
</td>
<td>
The number of decimal digits in [[Value]] when it is derived from a String (before applying its exponent part, and ignoring leading zeros), or 0 otherwise.
</td>
</tr>
<tr>
<td>
[[StringFractionDigitCount]]
</td>
<td>
a non-negative integer
</td>
<td>
The number of decimal fraction digits in [[Value]] when it is derived from a String (based on its mathemetical value, so accounting for any exponent), or 0 otherwise.
</td>
</tr>
</table>
</emu-table>
</emu-clause>
</ins>
<emu-clause id="sec-formatnumerictostring" oldids="sec-formatnumberstring" type="abstract operation" number="3">
<h1>
FormatNumericToString (
_intlObject_: an Object,
_x_: a mathematical value or ~negative-zero~,
<ins>_digitCount_: an integer,</ins>
<ins>_fractionDigitCount_: an integer,</ins>
): a Record with fields [[RoundedNumber]] (a mathematical value or ~negative-zero~) and [[FormattedString]] (a String)
</h1>
<dl class="header">
<dt>description</dt>
<dd>It rounds _x_ to <del>an Intl</del><ins>a</ins> mathematical value<ins> or ~negative-zero~</ins> according to the internal slots of _intlObject_. The [[RoundedNumber]] field contains the rounded result value and the [[FormattedString]] field contains a String value representation of that result formatted according to the internal slots of _intlObject_.</dd>
</dl>
<emu-alg>
1. Assert: _intlObject_ has [[RoundingMode]], [[RoundingType]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[RoundingIncrement]], and [[TrailingZeroDisplay]] internal slots.
1. If _x_ is ~negative-zero~, then
1. Let _sign_ be ~negative~.
1. Set _x_ to 0.
1. Else,
1. Assert: _x_ is a mathematical value.
1. If _x_ < 0, let _sign_ be ~negative~; else let _sign_ be ~positive~.
1. If _sign_ is ~negative~, then
1. Set _x_ to -_x_.
1. <ins>If _intlObject_.[[TrailingZeroDisplay]] is *"stripToMinimum"*, then</ins>
1. <ins>Set _digitCount_ to 0.</ins>
1. <ins>Set _fractionDigitCount_ to 0.</ins>
1. Let _unsignedRoundingMode_ be GetUnsignedRoundingMode(_intlObject_.[[RoundingMode]], _sign_).
1. If _intlObject_.[[RoundingType]] is ~significant-digits~, then
1. Let _result_ be ToRawPrecision(_x_, <ins>_digitCount_, _fractionDigitCount_,</ins> _intlObject_.[[MinimumSignificantDigits]], _intlObject_.[[MaximumSignificantDigits]], _unsignedRoundingMode_).
1. Else if _intlObject_.[[RoundingType]] is ~fraction-digits~, then
1. Let _result_ be ToRawFixed(_x_, <ins>_digitCount_, _fractionDigitCount_,</ins> _intlObject_.[[MinimumFractionDigits]], _intlObject_.[[MaximumFractionDigits]], _intlObject_.[[RoundingIncrement]], _unsignedRoundingMode_).
1. Else,
1. Let _sResult_ be ToRawPrecision(_x_, <ins>_digitCount_, _fractionDigitCount_,</ins> _intlObject_.[[MinimumSignificantDigits]], _intlObject_.[[MaximumSignificantDigits]], _unsignedRoundingMode_).
1. Let _fResult_ be ToRawFixed(_x_, <ins>_digitCount_, _fractionDigitCount_,</ins> _intlObject_.[[MinimumFractionDigits]], _intlObject_.[[MaximumFractionDigits]], _intlObject_.[[RoundingIncrement]], _unsignedRoundingMode_).
1. If _fResult_.[[RoundingMagnitude]] < _sResult_.[[RoundingMagnitude]], let _fixedIsMorePrecise_ be *true*; else let _fixedIsMorePrecise_ be *false*.
1. If _intlObject_.[[RoundingType]] is ~more-precision~ and _fixedIsMorePrecise_ is *true*, then
1. Let _result_ be _fResult_.
1. Else if _intlObject_.[[RoundingType]] is ~less-precision~ and _fixedIsMorePrecise_ is *false*, then
1. Let _result_ be _fResult_.
1. Else,
1. Let _result_ be _sResult_.
1. Set _x_ to _result_.[[RoundedNumber]].
1. Let _string_ be _result_.[[FormattedString]].
1. If _intlObject_.[[TrailingZeroDisplay]] is *"stripIfInteger"* and <emu-eqn>_x_ modulo 1 = 0</emu-eqn>, then
1. Let _i_ be StringIndexOf(_string_, *"."*, 0).
1. If _i_ is not ~not-found~, set _string_ to the substring of _string_ from 0 to _i_.
1. Let _int_ be _result_.[[IntegerDigitsCount]].
1. Let _minInteger_ be _intlObject_.[[MinimumIntegerDigits]].
1. If _int_ < _minInteger_, then
1. Let _forwardZeros_ be the String consisting of _minInteger_ - _int_ occurrences of the code unit 0x0030 (DIGIT ZERO).
1. Set _string_ to the string-concatenation of _forwardZeros_ and _string_.
1. If _sign_ is ~negative~, then
1. If _x_ is 0, set _x_ to ~negative-zero~. Otherwise, set _x_ to -_x_.
1. Return the Record { [[RoundedNumber]]: _x_, [[FormattedString]]: _string_ }.
</emu-alg>
</emu-clause>
<emu-clause id="sec-partitionnumberpattern" type="abstract operation">
<h1>
PartitionNumberPattern (
_numberFormat_: an object initialized as a NumberFormat,
_x_: <del>an Intl mathematical value</del><ins>a mathematical value or an Intl MV Record</ins>,
): a List of Records with fields [[Type]] (a String) and [[Value]] (a String)
</h1>
<dl class="header">
<dt>description</dt>
<dd>It creates the parts representing the mathematical value of _x_ according to the effective locale and the formatting options of _numberFormat_.</dd>
</dl>
<emu-alg>
1. <ins>If _x_ is an Intl MV Record, then</ins>
1. <ins>Let _digitCount_ be _x_.[[StringDigitCount]].</ins>
1. <ins>Let _fractionDigitCount_ be _x_.[[StringFractionDigitCount]].</ins>
1. <ins>Set _x_ to _x_.[[Value]].</ins>
1. <ins>Else,</ins>
1. <ins>Assert: _x_ is a mathematical value.</ins>
1. <ins>Let _digitCount_ be 0.</ins>
1. <ins>Let _fractionDigitCount_ be 0.</ins>
1. Let _exponent_ be 0.
1. If _x_ is ~not-a-number~, then
1. Let _n_ be an ILD String value indicating the *NaN* value.
1. Else if _x_ is ~positive-infinity~, then
1. Let _n_ be an ILD String value indicating positive infinity.
1. Else if _x_ is ~negative-infinity~, then
1. Let _n_ be an ILD String value indicating negative infinity.
1. Else,
1. If _x_ is not ~negative-zero~, then
1. Assert: _x_ is a mathematical value.
1. If _numberFormat_.[[Style]] is *"percent"*, set _x_ <del>be</del><ins>to</ins> 100 × _x_.
1. Set _exponent_ to ComputeExponent(_numberFormat_, _x_).
1. Set _x_ to _x_ × 10<sup>-_exponent_</sup>.
1. Let _formatNumberResult_ be FormatNumericToString(_numberFormat_, _x_<ins>, _digitCount_, _fractionDigitCount_</ins>).
1. Let _n_ be _formatNumberResult_.[[FormattedString]].
1. Set _x_ to _formatNumberResult_.[[RoundedNumber]].
1. Let _pattern_ be GetNumberFormatPattern(_numberFormat_, _x_).
1. Let _result_ be a new empty List.
1. Let _patternParts_ be PartitionPattern(_pattern_).
1. For each Record { [[Type]], [[Value]] } _patternPart_ of _patternParts_, do
1. Let _p_ be _patternPart_.[[Type]].
1. If _p_ is *"literal"*, then
1. Append the Record { [[Type]]: *"literal"*, [[Value]]: _patternPart_.[[Value]] } to _result_.
1. Else if _p_ is *"number"*, then
1. <ins>If _x_ is ~not-a-number~, then</ins>
1. <ins>Append the Record { [[Type]]: *"nan"*, [[Value]]: _n_ } to _result_.</ins>
1. <ins>Else if _x_ is ~positive-infinity~ or ~negative-infinity~, then</ins>
1. <ins>Append the Record { [[Type]]: *"infinity"*, [[Value]]: _n_ } to _result_.</ins>
1. <ins>Else,</ins>
1. Let _notationSubParts_ be PartitionNotationSubPattern(_numberFormat_, _x_, _n_, _exponent_).
1. Set _result_ to the list-concatenation of _result_ and _notationSubParts_.
1. Else if _p_ is *"plusSign"*, then
1. Let _plusSignSymbol_ be the ILND String representing the plus sign.
1. Append the Record { [[Type]]: *"plusSign"*, [[Value]]: _plusSignSymbol_ } to _result_.
1. Else if _p_ is *"minusSign"*, then
1. Let _minusSignSymbol_ be the ILND String representing the minus sign.
1. Append the Record { [[Type]]: *"minusSign"*, [[Value]]: _minusSignSymbol_ } to _result_.
1. Else if _p_ is *"percentSign"* and _numberFormat_.[[Style]] is *"percent"*, then
1. Let _percentSignSymbol_ be the ILND String representing the percent sign.
1. Append the Record { [[Type]]: *"percentSign"*, [[Value]]: _percentSignSymbol_ } to _result_.
1. Else if _p_ is *"unitPrefix"* and _numberFormat_.[[Style]] is *"unit"*, then
1. Let _unit_ be _numberFormat_.[[Unit]].
1. Let _unitDisplay_ be _numberFormat_.[[UnitDisplay]].
1. Let _mu_ be an ILD String value representing _unit_ before _x_ in _unitDisplay_ form, which may depend on _x_ in languages having different plural forms.
1. Append the Record { [[Type]]: *"unit"*, [[Value]]: _mu_ } to _result_.
1. Else if _p_ is *"unitSuffix"* and _numberFormat_.[[Style]] is *"unit"*, then
1. Let _unit_ be _numberFormat_.[[Unit]].
1. Let _unitDisplay_ be _numberFormat_.[[UnitDisplay]].
1. Let _mu_ be an ILD String value representing _unit_ after _x_ in _unitDisplay_ form, which may depend on _x_ in languages having different plural forms.
1. Append the Record { [[Type]]: *"unit"*, [[Value]]: _mu_ } to _result_.
1. Else if _p_ is *"currencyCode"* and _numberFormat_.[[Style]] is *"currency"*, then
1. Let _currency_ be _numberFormat_.[[Currency]].
1. Let _cd_ be _currency_.
1. Append the Record { [[Type]]: *"currency"*, [[Value]]: _cd_ } to _result_.
1. Else if _p_ is *"currencyPrefix"* and _numberFormat_.[[Style]] is *"currency"*, then
1. Let _currency_ be _numberFormat_.[[Currency]].
1. Let _currencyDisplay_ be _numberFormat_.[[CurrencyDisplay]].
1. Let _cd_ be an ILD String value representing _currency_ before _x_ in _currencyDisplay_ form, which may depend on _x_ in languages having different plural forms.
1. Append the Record { [[Type]]: *"currency"*, [[Value]]: _cd_ } to _result_.
1. Else if _p_ is *"currencySuffix"* and _numberFormat_.[[Style]] is *"currency"*, then
1. Let _currency_ be _numberFormat_.[[Currency]].
1. Let _currencyDisplay_ be _numberFormat_.[[CurrencyDisplay]].
1. Let _cd_ be an ILD String value representing _currency_ after _x_ in _currencyDisplay_ form, which may depend on _x_ in languages having different plural forms. If the implementation does not have such a representation of _currency_, use _currency_ itself.
1. Append the Record { [[Type]]: *"currency"*, [[Value]]: _cd_ } to _result_.
1. Else,
1. Let _unknown_ be an ILND String based on _x_ and _p_.
1. Append the Record { [[Type]]: *"unknown"*, [[Value]]: _unknown_ } to _result_.
1. Return _result_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-partitionnotationsubpattern" type="abstract operation">
<h1>
PartitionNotationSubPattern (
_numberFormat_: an Intl.NumberFormat,
_x_: <del>an Intl mathematical value</del><ins>a mathematical value or ~negative-zero~</ins>,
_n_: a String,
_exponent_: an integer,
): a List of Records with fields [[Type]] (a String) and [[Value]] (a String)
</h1>
<dl class="header">
<dt>description</dt>
<dd>
_x_ is <del>an Intl</del><ins>a</ins> mathematical value after rounding is applied and _n_ is an intermediate formatted string.
It creates the corresponding parts for the number and notation according to the effective locale and the formatting options of _numberFormat_.
</dd>
</dl>
<emu-alg>
1. Let _result_ be a new empty List.
1. <del>If _x_ is ~not-a-number~, then</del>
1. <del>Append the Record { [[Type]]: *"nan"*, [[Value]]: _n_ } to _result_.</del>
1. <del>Else if _x_ is ~positive-infinity~ or ~negative-infinity~, then</del>
1. <del>Append the Record { [[Type]]: *"infinity"*, [[Value]]: _n_ } to _result_.</del>
1. <del>Else,</del>
1. Let _notationSubPattern_ be GetNotationSubPattern(_numberFormat_, _exponent_).
1. Let _patternParts_ be PartitionPattern(_notationSubPattern_).
1. For each Record { [[Type]], [[Value]] } _patternPart_ of _patternParts_, do
1. Let _p_ be _patternPart_.[[Type]].
1. If _p_ is *"literal"*, then
1. Append the Record { [[Type]]: *"literal"*, [[Value]]: _patternPart_.[[Value]] } to _result_.
1. Else if _p_ is *"number"*, then
1. ...
1. Else if _p_ is *"compactSymbol"*, then
1. ...
1. Else if _p_ is *"compactName"*, then
1. ...
1. Else if _p_ is *"scientificSeparator"*, then
1. ...
1. Else if _p_ is *"scientificExponent"*, then
1. If _exponent_ < 0, then
1. Let _minusSignSymbol_ be the ILND String representing the minus sign.
1. Append the Record { [[Type]]: *"exponentMinusSign"*, [[Value]]: _minusSignSymbol_ } to _result_.
1. Let _exponent_ be -_exponent_.
1. Let _exponentResult_ be ToRawFixed(_exponent_,<ins> 0, 0,</ins> 0, 0, 1, *undefined*).
1. Append the Record { [[Type]]: *"exponentInteger"*, [[Value]]: _exponentResult_.[[FormattedString]] } to _result_.
1. Else,
1. Let _unknown_ be an ILND String based on _x_ and _p_.
1. Append the Record { [[Type]]: *"unknown"*, [[Value]]: _unknown_ } to _result_.
1. Return _result_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-formatnumber" type="abstract operation">
<h1>
FormatNumeric (
_numberFormat_: an Intl.NumberFormat,
_x_: <del>an Intl mathematical value</del><ins>a mathematical value or an Intl MV Record</ins>,
): a String
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Let _parts_ be PartitionNumberPattern(_numberFormat_, _x_).
1. Let _result_ be the empty String.
1. For each Record { [[Type]], [[Value]] } _part_ of _parts_, do
1. Set _result_ to the string-concatenation of _result_ and _part_.[[Value]].
1. Return _result_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-torawprecision" type="abstract operation" number="8">
<h1>
ToRawPrecision (
_x_: a non-negative mathematical value,
<ins>_digitCount_: an integer,</ins>
<ins>_fractionDigitCount_: an integer,</ins>
_minPrecision_: an integer in the inclusive interval from 1 to 21,
_maxPrecision_: an integer in the inclusive interval from 1 to 21,
_unsignedRoundingMode_: a specification type from the Unsigned Rounding Mode column of <emu-xref href="#table-intl-unsigned-rounding-modes"></emu-xref>, or *undefined*,
): a Record with fields [[FormattedString]] (a String), [[RoundedNumber]] (a mathematical value), [[IntegerDigitsCount]] (an integer), and [[RoundingMagnitude]] (an integer)
</h1>
<dl class="header">
<dt>description</dt>
<dd>
<p>It involves solving the following equation, which returns a valid mathematical value given integer inputs:</p>
<emu-eqn id="eqn-ToRawPrecisionFn" aoid="ToRawPrecisionFn">
ToRawPrecisionFn(_n_, _e_, _p_) = _n_ × 10<sup>_e_–_p_+1</sup>
where 10<sup>_p_–1</sup> ≤ _n_ < 10<sup>_p_</sup>
</emu-eqn>
</dd>
</dl>
<emu-alg>
1. Let _p_ be _maxPrecision_.
1. If _x_ = 0, then
1. Let _m_ be the String consisting of _p_ occurrences of the code unit 0x0030 (DIGIT ZERO).
1. Let _e_ be 0.
1. Let _xFinal_ be 0.
1. Else,
1. [declared="n1,e1,r1"] Let _n1_ and _e1_ each be an integer and _r1_ a mathematical value, with <emu-eqn>_r1_ = ToRawPrecisionFn(_n1_, _e1_, _p_)</emu-eqn>, such that <emu-eqn>_r1_ ≤ _x_</emu-eqn> and _r1_ is maximized.
1. [declared="n2,e2,r2"] Let _n2_ and _e2_ each be an integer and _r2_ a mathematical value, with <emu-eqn>_r2_ = ToRawPrecisionFn(_n2_, _e2_, _p_)</emu-eqn>, such that <emu-eqn>_r2_ ≥ _x_</emu-eqn> and _r2_ is minimized.
1. Let _xFinal_ be ApplyUnsignedRoundingMode(_x_, _r1_, _r2_, _unsignedRoundingMode_).
1. If _xFinal_ is _r1_, then
1. Let _n_ be _n1_.
1. Let _e_ be _e1_.
1. Else,
1. Let _n_ be _n2_.
1. Let _e_ be _e2_.
1. Let _m_ be the String consisting of the digits of the decimal representation of _n_ (in order, with no leading zeroes).
1. <ins>If every code unit of _m_ is 0x0030 (DIGIT ZERO), let _isZero_ be *true*; else let _isZero_ be *false*.</ins>
1. If _e_ ≥ (_p_ - 1), then
1. Set _m_ to the string-concatenation of _m_ and _e_ - _p_ + 1 occurrences of the code unit 0x0030 (DIGIT ZERO).
1. Let _int_ be _e_ + 1.
1. Else if _e_ ≥ 0, then
1. Set _m_ to the string-concatenation of the first _e_ + 1 code units of _m_, the code unit 0x002E (FULL STOP), and the remaining _p_ - (_e_ + 1) code units of _m_.
1. Let _int_ be _e_ + 1.
1. Else,
1. Assert: _e_ < 0.
1. Set _m_ to the string-concatenation of *"0."*, -(_e_ + 1) occurrences of the code unit 0x0030 (DIGIT ZERO), and _m_.
1. Let _int_ be 1.
1. <ins>If _isZero_ is *true*, let _resolvedMinPrecision_ be max(_minPrecision_, _fractionDigitCount_ + 1); else let _resolvedMinPrecision_ be max(_minPrecision_, _digitCount_).</ins>
1. If _m_ contains the code unit 0x002E (FULL STOP) and _maxPrecision_ > <del>_minPrecision_</del><ins>_resolvedMinPrecision_</ins>, then
1. Let _cut_ be _maxPrecision_ - <del>_minPrecision_</del><ins>_resolvedMinPrecision_</ins>.
1. Repeat, while _cut_ > 0 and the last code unit of _m_ is 0x0030 (DIGIT ZERO),
1. Remove the last code unit from _m_.
1. Set _cut_ to _cut_ - 1.
1. If the last code unit of _m_ is 0x002E (FULL STOP), then
1. Remove the last code unit from _m_.
1. Return the Record { [[FormattedString]]: _m_, [[RoundedNumber]]: _xFinal_, [[IntegerDigitsCount]]: _int_, [[RoundingMagnitude]]: _e_–_p_+1 }.
</emu-alg>
</emu-clause>
<emu-clause id="sec-torawfixed" type="abstract operation">
<h1>
ToRawFixed (
_x_: a non-negative mathematical value,
<ins>_digitCount_: an integer,</ins>
<ins>_fractionDigitCount_: an integer,</ins>
_minFraction_: an integer in the inclusive interval from 0 to 100,
_maxFraction_: an integer in the inclusive interval from 0 to 100,
_roundingIncrement_: an integer,
_unsignedRoundingMode_: a specification type from the Unsigned Rounding Mode column of <emu-xref href="#table-intl-unsigned-rounding-modes"></emu-xref>, or *undefined*,
): a Record with fields [[FormattedString]] (a String), [[RoundedNumber]] (a mathematical value), [[IntegerDigitsCount]] (an integer), and [[RoundingMagnitude]] (an integer)
</h1>
<dl class="header">
<dt>description</dt>
<dd>
<p>It involves solving the following equation, which returns a valid mathematical value given integer inputs:</p>
<emu-eqn id="eqn-ToRawFixedFn" aoid="ToRawFixedFn">
ToRawFixedFn(_n_, _f_) = _n_ × 10<sup>–_f_</sup>
</emu-eqn>
</dd>
</dl>
<emu-alg>
1. Let _f_ be _maxFraction_.
1. [declared="n1,r1"] Let _n1_ be an integer and _r1_ a mathematical value, with <emu-eqn>_r1_ = ToRawFixedFn(_n1_, _f_)</emu-eqn>, such that <emu-eqn>_n1_ modulo _roundingIncrement_ = 0</emu-eqn>, <emu-eqn>_r1_ ≤ _x_</emu-eqn>, and _r1_ is maximized.
1. [declared="n2,r2"] Let _n2_ be an integer and _r2_ a mathematical value, with <emu-eqn>_r2_ = ToRawFixedFn(_n2_, _f_)</emu-eqn>, such that <emu-eqn>_n2_ modulo _roundingIncrement_ = 0</emu-eqn>, <emu-eqn>_r2_ ≥ _x_</emu-eqn>, and _r2_ is minimized.
1. Let _xFinal_ be ApplyUnsignedRoundingMode(_x_, _r1_, _r2_, _unsignedRoundingMode_).
1. If _xFinal_ is _r1_, let _n_ be _n1_. Otherwise, let _n_ be _n2_.
1. If _n_ = 0, let _m_ be *"0"*. Otherwise, let _m_ be the String consisting of the digits of the decimal representation of _n_ (in order, with no leading zeroes).
1. If _f_ ≠ 0, then
1. Let _k_ be the length of _m_.
1. If _k_ ≤ _f_, then
1. <ins>Let _zn_ be _f_ + 1 - _k_.</ins>
1. Let _z_ be the String value consisting of <del>_f_ + 1 - _k_</del><ins>_zn_</ins> occurrences of the code unit 0x0030 (DIGIT ZERO).
1. Set _m_ to the string-concatenation of _z_ and _m_.
1. Set _k_ to _f_ + 1.
1. <ins>Else,</ins>
1. <ins>Let _zn_ be 0.</ins>
1. Let _a_ be the first _k_ - _f_ code units of _m_, and let _b_ be the remaining _f_ code units of _m_.
1. <del>Set _m_ to the string-concatenation of _a_, *"."*, and _b_.</del>
1. Let _int_ be the length of _a_.
1. <ins>If every code unit of _m_ is 0x0030 (DIGIT ZERO), then</ins>
1. <ins>Let _sfc_ be _fractionDigitCount_.</ins>
1. <ins>Else if _n_ = 0, then</ins>
1. <ins>Let _sfc_ be _digitCount_ - _int_.</ins>
1. <ins>Else,</ins>
1. <ins>Let _sfc_ be _digitCount_ - _int_ + _zn_.</ins>
1. <ins>Let _cut_ be _maxFraction_ - max(_sfc_, _minFraction_).</ins>
1. <ins>Repeat, while _cut_ > 0 and the last code unit of _b_ is 0x0030 (DIGIT ZERO),</ins>
1. <ins>Remove the last code unit from _b_.</ins>
1. <ins>Set _cut_ to _cut_ - 1.</ins>
1. <ins>If _b_ is the empty String, set _m_ to _a_; else set _m_ to the string-concatenation of _a_, *"."*, and _b_.</ins>
1. Else,
1. Let _int_ be the length of _m_.
1. <del>Let _cut_ be _maxFraction_ - _minFraction_.</del>
1. <del>Repeat, while _cut_ > 0 and the last code unit of _m_ is 0x0030 (DIGIT ZERO),</del>
1. <del>Remove the last code unit from _m_.</del>
1. <del>Set _cut_ to _cut_ - 1.</del>
1. <del>If the last code unit of _m_ is 0x002E (FULL STOP), then</del>
1. <del>Remove the last code unit from _m_.</del>
1. Return the Record { [[FormattedString]]: _m_, [[RoundedNumber]]: _xFinal_, [[IntegerDigitsCount]]: _int_, [[RoundingMagnitude]]: –_f_ }.
</emu-alg>
</emu-clause>
<emu-clause id="sec-getnumberformatpattern" type="abstract operation" number="11">
<h1>
GetNumberFormatPattern (
_numberFormat_: an Intl.NumberFormat,
_x_: <del>an Intl mathematical value</del><ins>either a mathematical value or one of ~positive-infinity~, ~negative-infinity~, ~not-a-number~, or ~negative-zero~</ins>,
): a String
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It considers the resolved unit-related options in the number format object along with the final scaled and rounded number being formatted<del>(an Intl mathematical value)</del> and returns a pattern, a String value as described in <emu-xref href="#sec-intl.numberformat-internal-slots"></emu-xref>.
</dd>
</dl>
<emu-alg>
1. ...
</emu-alg>
</emu-clause>
<emu-clause id="sec-computeexponent" type="abstract operation" number="13">
<h1>
ComputeExponent (
_numberFormat_: an Intl.NumberFormat,
_x_: a mathematical value,
): an integer
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It computes an exponent (power of ten) by which to scale _x_ according to the number formatting settings.
It handles cases such as 999 rounding up to 1000, requiring a different exponent.
</dd>
</dl>
<emu-alg>
1. If _x_ = 0, then
1. Return 0.
1. If _x_ < 0, then
1. Let _x_ = -_x_.
1. Let _magnitude_ be floor(log10(_x_)).
1. Let _exponent_ be ComputeExponentForMagnitude(_numberFormat_, _magnitude_).
1. Let _x_ be _x_ × 10<sup>-_exponent_</sup>.
1. Let _formatNumberResult_ be FormatNumericToString(_numberFormat_, _x_<ins>, 0, 0</ins>).
1. If _formatNumberResult_.[[RoundedNumber]] = 0, then
1. Return _exponent_.
1. Let _newMagnitude_ be floor(log10(_formatNumberResult_.[[RoundedNumber]])).
1. If _newMagnitude_ is _magnitude_ - _exponent_, then
1. Return _exponent_.
1. Return ComputeExponentForMagnitude(_numberFormat_, _magnitude_ + 1).
</emu-alg>
</emu-clause>
<emu-clause id="sec-runtime-semantics-stringintlmv" type="sdo" number="15">
<h1>Runtime Semantics: StringIntlMV</h1>
<dl class="header">
</dl>
<emu-note>
<del class="block">
<p>
The
conversion of a |StringNumericLiteral| to a Number value is similar overall to the determination of the NumericValue of a |NumericLiteral| (see <emu-xref href="#sec-literals-numeric-literals"></emu-xref>), but some of the details are different.
</p>
</del>
<ins class="block">
<p>
The conversion of a |StringNumericLiteral| to a mathematical value
is similar overall to the determination of the NumericValue of a |NumericLiteral| (see <emu-xref href="#sec-literals-numeric-literals"></emu-xref>),
but some of the details are different, and additional information is retained.
The result of StringIntlMV is an Intl MV Record.
</p>
</ins>
</emu-note>
<emu-grammar>StringNumericLiteral ::: StrWhiteSpace?</emu-grammar>
<emu-alg>
1. Return <del>0</del><ins>the Intl MV Record { [[Value]]: 0, [[StringDigitCount]]: 0, [[StringFractionDigitCount]]: 0 }</ins>.
</emu-alg>
<emu-grammar>StringNumericLiteral ::: StrWhiteSpace? StrNumericLiteral StrWhiteSpace?</emu-grammar>
<emu-alg>
1. Return StringIntlMV of |StrNumericLiteral|.
</emu-alg>
<emu-grammar>StrNumericLiteral ::: NonDecimalIntegerLiteral</emu-grammar>
<emu-alg>
1. <del>Return MV of |NonDecimalIntegerLiteral|.</del>
1. <ins>Let _i_ be MV of |NonDecimalIntegerLiteral|.</ins>
1. <ins>Return the Intl MV Record { [[Value]]: _i_, [[StringDigitCount]]: 0, [[StringFractionDigitCount]]: 0 }.</ins>
</emu-alg>
<emu-grammar>StrDecimalLiteral ::: `-` StrUnsignedDecimalLiteral</emu-grammar>
<emu-alg>
1. Let <del>_a_</del><ins>_x_</ins> be StringIntlMV of |StrUnsignedDecimalLiteral|.
1. <ins>Let _a_ be _x_.[[Value]].</ins>
1. If _a_ is 0, <del>return ~negative-zero~</del><ins>set _x_.[[Value]] to ~negative-zero~</ins>.
1. <del>If</del><ins>Else if</ins> _a_ is ~positive-infinity~, <del>return ~negative-infinity~</del><ins>set _x_.[[Value]] to ~negative-infinity~</ins>.
1. <ins>Else, set _x_.[[Value]] to -_a_.</ins>
1. Return <del>-_a_</del><ins>_x_</ins>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: `Infinity`</emu-grammar>
<emu-alg>
1. Return <del>~positive-infinity~</del><ins>the Intl MV Record { [[Value]]: ~positive-infinity~, [[StringDigitCount]]: 0, [[StringFractionDigitCount]]: 0 }</ins>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: DecimalDigits `.` DecimalDigits? ExponentPart?</emu-grammar>
<emu-alg>
1. <del>Let _a_ be MV of the first |DecimalDigits|.</del>
1. <del>If the second |DecimalDigits| is present, then</del>
1. <del>Let _b_ be MV of the second |DecimalDigits|.</del>
1. <del>Let _n_ be the number of code points in the second |DecimalDigits|.</del>
1. <del>Else,</del>
1. <del>Let _b_ be 0.</del>
1. <del>Let _n_ be 0.</del>
1. <ins>Let _intPart_ be the first |DecimalDigits|.</ins>
1. <ins>If the second |DecimalDigits| is present, let _fracPart_ be the second |DecimalDigits|; else let _fracPart_ be ~empty~.</ins>
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|<del>. Otherwise,</del><ins>; else</ins> let _e_ be 0.
1. Return <del>(_a_ + (_b_ × 10<sup>-_n_</sup>)) × 10<sup>_e_</sup></del><ins>StringIntlMVFromParts(_intPart_, _fracPart_, _e_)</ins>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: `.` DecimalDigits ExponentPart?</emu-grammar>
<emu-alg>
1. <del>Let _b_ be MV of |DecimalDigits|.</del>
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|<del>. Otherwise,</del><ins>; else</ins> let _e_ be 0.
1. <del>Let _n_ be the number of code points in |DecimalDigits|.</del>
1. Return <del>_b_ × 10<sup>_e_ - _n_</sup></del><ins>StringIntlMVFromParts(~empty~, |DecimalDigits|, _e_)</ins>.
</emu-alg>
<emu-grammar>StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPart?</emu-grammar>
<emu-alg>
1. <del>Let _a_ be MV of |DecimalDigits|.</del>
1. If |ExponentPart| is present, let _e_ be MV of |ExponentPart|<del>. Otherwise,</del><ins>; else</ins> let _e_ be 0.
1. Return <del>_a_ × 10<sup>_e_</sup></del><ins>StringIntlMVFromParts(|DecimalDigits|, ~empty~, _e_)</ins>.
</emu-alg>
</emu-clause>
<ins class="block">
<emu-clause id="sec-stringintlmvfromparts" type="abstract operation">
<h1>
<ins>StringIntlMVFromParts (
_intPart_: a Parse Node or ~empty~,
_fracPart_: a Parse Node or ~empty~,
_e_: a mathematical value,
): an Intl MV Record</ins>
</h1>
<dl class="header">
<dt>description</dt>
<dd></dd>
</dl>
<emu-alg>
1. If _intPart_ is ~empty~, then
1. Let _a_ be 0.
1. Let _m_ be 0.
1. Let _z_ be 0.
1. Else,
1. Let _a_ be MV of _intPart_.
1. Let _m_ be the number of code points in _intPart_.
1. Assert: _m_ > 0.
1. Let _z_ be the count of leading U+0030 (DIGIT ZERO) code points in _intPart_.
1. If _fracPart_ is ~empty~, then
1. Let _b_ be 0.
1. Let _n_ be 0.
1. Else,
1. Let _b_ be MV of _fracPart_.
1. Let _n_ be the number of code points in _fracPart_.
1. Assert: _n_ > 0.
1. If _a_ = 0, then
1. Let _zn_ be the count of leading U+0030 (DIGIT ZERO) code points in _fracPart_.
1. Set _z_ to _z_ + _zn_.
1. Let _value_ be (_a_ + (_b_ × 10<sup>-_n_</sup>)) × 10<sup>_e_</sup>.
1. If _a_ = 0 and _b_ = 0, let _digitCount_ be 1 + _n_; else let _digitCount_ be _m_ + _n_ - _z_.
1. Let _fractionDigitCount_ be max(0, _n_ - _e_).
1. Return the Intl MV Record { [[Value]]: _value_, [[StringDigitCount]]: _digitCount_, [[StringFractionDigitCount]]: _fractionDigitCount_ }.
</emu-alg>
</emu-clause>
</ins>
<emu-clause id="sec-tointlmathematicalvalue" type="abstract operation">
<del class="block">
<h1>
ToIntlMathematicalValue (
_value_: an ECMAScript language value,
): either a normal completion containing an Intl mathematical value or a throw completion
</h1>
</del>
<ins class="block">
<h1>
ToIntlMathematicalValue (
_value_: an ECMAScript language value,
): either a normal completion containing an Intl MV Record or a throw completion
</h1>
</ins>
<dl class="header">
<dt>description</dt>
<dd>
<del>It returns _value_ converted to an <dfn id="intl-mathematical-value">Intl mathematical value</dfn>, which is a mathematical value together with ~positive-infinity~, ~negative-infinity~, ~not-a-number~, and ~negative-zero~.</del>
This abstract operation is similar to <emu-xref href="#sec-tonumeric"></emu-xref>, but <del>a mathematical value can be returned instead of a Number or BigInt, so that exact decimal values can be represented</del><ins>it retains the full precision of numeric strings</ins>.
</dd>
</dl>
<emu-alg>
1. Let _primValue_ be ? ToPrimitive(_value_, ~number~).
1. If _primValue_ is a BigInt, return <del>ℝ(_primValue_)</del><ins>the Intl MV Record { [[Value]]: ℝ(_primValue_), [[StringDigitCount]]: 0, [[StringFractionDigitCount]]: 0 }</ins>.
1. If _primValue_ is a String, then
1. Let _str_ be _primValue_.
1. Else,
1. Let _x_ be ? ToNumber(_primValue_).
1. If _x_ is *-0*<sub>𝔽</sub>, return <del>~negative-zero~</del><ins>the Intl MV Record { [[Value]]: ~negative-zero~, [[StringDigitCount]]: 0, [[StringFractionDigitCount]]: 0 }</ins>.
1. Let _str_ be Number::toString(_x_, 10).
1. Let _text_ be StringToCodePoints(_str_).
1. Let _literal_ be ParseText(_text_, |StringNumericLiteral|).
1. If _literal_ is a List of errors, return <del>~not-a-number~</del><ins>the Intl MV Record { [[Value]]: ~not-a-number~, [[StringDigitCount]]: 0, [[StringFractionDigitCount]]: 0 }</ins>.
1. Let <del>_intlMV_</del><ins>_stringData_</ins> be the StringIntlMV of _literal_.
1. <ins>Let _value_ be _stringData_.[[Value]].</ins>
1. <ins>If _primValue_ is a String, then</ins>
1. <ins>Let _digitCount_ be _stringData_.[[StringDigitCount]].</ins>
1. <ins>Let _fractionDigitCount_ be _stringData_.[[StringFractionDigitCount]].</ins>
1. <ins>Else,</ins>
1. <ins>Let _digitCount_ be 0.</ins>
1. <ins>Let _fractionDigitCount_ be 0.</ins>
1. If <del>_intlMV_</del><ins>_value_</ins> is a mathematical value, then
1. Let _rounded_ be RoundMVResult(abs(<del>_intlMV_</del><ins>_value_</ins>)).
1. <del>If _rounded_ is *+∞*<sub>𝔽</sub> and _intlMV_ < 0, return ~negative-infinity~.</del>
1. <del>If _rounded_ is *+∞*<sub>𝔽</sub>, return ~positive-infinity~.</del>
1. <ins>If _rounded_ is *+∞*<sub>𝔽</sub>, then</ins>
1. <ins>If _value_ < 0, set _value_ to ~negative-infinity~; else set _value_ to ~positive-infinity~.</ins>
1. <ins>Set _digitCount_ to 0.</ins>
1. <del>If _rounded_ is *+0*<sub>𝔽</sub> and _intlMV_ < 0, return ~negative-zero~.</del>
1. <del>If _rounded_ is *+0*<sub>𝔽</sub>, return 0.</del>
1. <ins>Else if _rounded_ is *+0*<sub>𝔽</sub>, then</ins>
1. <ins>If _value_ < 0, set _value_ to ~negative-zero~; else set _value_ to 0.</ins>
1. NOTE: The value of _digitCount_ is retained.
1. Return <del>_intlMV_</del><ins>the Intl MV Record { [[Value]]: _value_, [[StringDigitCount]]: _digitCount_, [[StringFractionDigitCount]]: _fractionDigitCount_ }</ins>.
</emu-alg>
</emu-clause>
<emu-clause id="sec-partitionnumberrangepattern" type="abstract operation">
<h1>
PartitionNumberRangePattern (
_numberFormat_: an Intl.NumberFormat,
_x_: an <del>Intl mathematical value</del><ins>Intl MV Record</ins>,
_y_: an <del>Intl mathematical value</del><ins>Intl MV Record</ins>,
): either a normal completion containing a List of Records with fields [[Type]] (a String), [[Value]] (a String), and [[Source]] (a String), or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It creates the parts for a localized number range according to _x_, _y_, and the formatting options of _numberFormat_.</dd>
</dl>
<emu-alg>
1. If _x_<ins>.[[Value]]</ins> is ~not-a-number~ or _y_<ins>.[[Value]]</ins> is ~not-a-number~, throw a *RangeError* exception.
1. Let _xResult_ be PartitionNumberPattern(_numberFormat_, _x_).
1. Let _yResult_ be PartitionNumberPattern(_numberFormat_, _y_).
1. If FormatNumeric(_numberFormat_, _x_) is FormatNumeric(_numberFormat_, _y_), then
1. Let _appxResult_ be FormatApproximately(_numberFormat_, _xResult_).
1. For each element _r_ of _appxResult_, do
1. Set _r_.[[Source]] to *"shared"*.
1. Return _appxResult_.
1. Let _result_ be a new empty List.
1. For each element _r_ of _xResult_, do
1. Append the Record { [[Type]]: _r_.[[Type]], [[Value]]: _r_.[[Value]], [[Source]]: *"startRange"* } to _result_.
1. Let _rangeSeparator_ be an ILND String value used to separate two numbers.
1. Append the Record { [[Type]]: *"literal"*, [[Value]]: _rangeSeparator_, [[Source]]: *"shared"* } to _result_.
1. For each element _r_ of _yResult_, do
1. Append the Record { [[Type]]: _r_.[[Type]], [[Value]]: _r_.[[Value]], [[Source]]: *"endRange"* } to _result_.
1. Return CollapseNumberRange(_numberFormat_, _result_).
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="pluralrules-objects">
<h1>PluralRules Objects</h1>
<emu-clause id="sec-properties-of-intl-pluralrules-instances" number="4">
<h1>Properties of Intl.PluralRules Instances</h1>
<ul>
<li>...</li>
<li>[[TrailingZeroDisplay]] is one of the String values *"auto"*<del> or</del><ins>,</ins> *"stripIfInteger"*<ins>, or *"stripToMinimum"*</ins>, indicating whether to <ins>retain them when possible,</ins> strip trailing zeros if the formatted number is an integer (i.e., has no non-zero fraction digit)<ins>, or strip them at positions beyond the minimum count of fraction or significant digits, as applicable</ins>.</li>
</ul>
</emu-clause>
<emu-clause id="sec-intl-pluralrules-abstracts">
<h1>Abstract Operations for PluralRules Objects</h1>
<emu-clause id="sec-resolveplural" type="abstract operation" number="2">
<h1>
ResolvePlural (
_pluralRules_: an Intl.PluralRules,
<del>_n_: an Intl mathematical value,</del>
<ins>_intlMV_: an Intl MV Record,</ins>
): a Record with fields [[PluralCategory]] (*"zero"*, *"one"*, *"two"*, *"few"*, *"many"*, or *"other"*) and [[FormattedString]] (a String)
</h1>
<dl class="header">
<dt>description</dt>
<dd>The returned Record contains two string-valued fields describing <del>_n_</del><ins>_intlMV_</ins> according to the effective locale and the internal slots of _pluralRules_: [[PluralCategory]] characterizing its <emu-xref href="#sec-pluralruleselect">plural category</emu-xref>, and [[FormattedString]] containing its formatted representation.</dd>
</dl>
<emu-alg>
1. <ins>Let _n_ be _intlMV_.[[Value]].</ins>
1. If _n_ is ~not-a-number~, then
1. Let _s_ be an ILD String value indicating the *NaN* value.
1. Return the Record { [[PluralCategory]]: *"other"*, [[FormattedString]]: _s_ }.
1. If _n_ is ~positive-infinity~, then
1. Let _s_ be an ILD String value indicating positive infinity.
1. Return the Record { [[PluralCategory]]: *"other"*, [[FormattedString]]: _s_ }.
1. If _n_ is ~negative-infinity~, then
1. Let _s_ be an ILD String value indicating negative infinity.
1. Return the Record { [[PluralCategory]]: *"other"*, [[FormattedString]]: _s_ }.
1. <ins>Let _digitCount_ be _intlMV_.[[StringDigitCount]].</ins>
1. <ins>Let _fractionDigitCount_ be _intlMV_.[[StringFractionDigitCount]].</ins>
1. Let _res_ be FormatNumericToString(_pluralRules_, _n_<ins>, _digitCount_, _fractionDigitCount_</ins>).
1. Let _s_ be _res_.[[FormattedString]].
1. Let _locale_ be _pluralRules_.[[Locale]].
1. Let _type_ be _pluralRules_.[[Type]].
1. Let _notation_ be _pluralRules_.[[Notation]].
1. Let _compactDisplay_ be _pluralRules_.[[CompactDisplay]].
1. Let _p_ be PluralRuleSelect(_locale_, _type_, _notation_, _compactDisplay_, _s_).
1. Return the Record { [[PluralCategory]]: _p_, [[FormattedString]]: _s_ }.
</emu-alg>
</emu-clause>
<emu-clause id="sec-resolvepluralrange" type="abstract operation" number="4">
<h1>
ResolvePluralRange (
_pluralRules_: an Intl.PluralRules,
_x_: an <del>Intl mathematical value</del><ins>Intl MV Record</ins>,
_y_: an <del>Intl mathematical value</del><ins>Intl MV Record</ins>,
): either a normal completion containing either *"zero"*, *"one"*, *"two"*, *"few"*, *"many"*, or *"other"*, or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>The returned String value represents the plural form of the range starting from _x_ and ending at _y_ according to the effective locale and the internal slots of _pluralRules_.</dd>
</dl>
<emu-alg>
1. If _x_<ins>.[[Value]]</ins> is ~not-a-number~ or _y_<ins>.[[Value]]</ins> is ~not-a-number~, throw a *RangeError* exception.
1. Let _xp_ be ResolvePlural(_pluralRules_, _x_).
1. Let _yp_ be ResolvePlural(_pluralRules_, _y_).
1. If _xp_.[[FormattedString]] is _yp_.[[FormattedString]], then
1. Return _xp_.[[PluralCategory]].
1. Let _locale_ be _pluralRules_.[[Locale]].
1. Let _type_ be _pluralRules_.[[Type]].
1. Let _notation_ be _pluralRules_.[[Notation]].
1. Let _compactDisplay_ be _pluralRules_.[[CompactDisplay]].
1. Return PluralRuleSelectRange(_locale_, _type_, _notation_, _compactDisplay_, _xp_.[[PluralCategory]], _yp_.[[PluralCategory]]).
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>