Skip to content

Commit 75279e5

Browse files
ptomatoMs2ger
authored andcommitted
Editorial: Use the rounding abstract operations from Intl.NumberFormat V3
We intend to standardize on the same rounding modes as Intl.NumberFormat (see #1038), so it makes sense to use the same abstract operations, namely GetUnsignedRoundingMode and ApplyUnsignedRoundingMode. Note that this does not yet add user-visible support for the full set of rounding modes that Intl.NumberFormat does; that (#1038) is a normative change that we'll apply once Intl.NumberFormat goes to Stage 4. However, this way of expressing rounding makes it easier to make that change in the future, and makes it easier to address #2191 in the short term. RoundTowardsZero stays the same, since that is used for several other things as well as rounding according to a rounding mode.
1 parent 7a4a518 commit 75279e5

File tree

6 files changed

+187
-37
lines changed

6 files changed

+187
-37
lines changed

spec/abstractops.html

Lines changed: 173 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -651,40 +651,190 @@ <h1>
651651
</emu-alg>
652652
</emu-clause>
653653

654-
<emu-clause id="sec-temporal-roundhalfawayfromzero" aoid="RoundHalfAwayFromZero">
655-
<h1>RoundHalfAwayFromZero ( _x_ )</h1>
654+
<emu-clause id="sec-temporal-getunsignedroundingmode" type="abstract operation">
655+
<h1>
656+
GetUnsignedRoundingMode (
657+
_roundingMode_: *"ceil"*, *"floor"*, *"expand"*, *"trunc"*, *"halfCeil"*, *"halfFloor"*, *"halfExpand"*, *"halfTrunc"*, or *"halfEven"*,
658+
_isNegative_: *true* or *false*,
659+
): ~zero~, ~infinity~, ~half-zero~, ~half-infinity~, or ~half-even~
660+
</h1>
661+
<dl class="header">
662+
<dt>description</dt>
663+
<dd>
664+
The return value is the rounding mode that should be applied to the absolute value of a number to produce the same result as if _roundingMode_ were applied to the signed value of the number (negative if _isNegative_ is *true*, or positive otherwise).
665+
</dd>
666+
</dl>
656667
<emu-alg>
657-
1. Assert: _x_ is a mathematical value.
658-
1. Return the mathematical value that is closest to _x_ and is an integer.
659-
If two integers are equally close to _x_, then the result is the integer that is farther away from 0. If _x_ is already an integer, then the result is _x_.
668+
1. If _isNegative_ is *true*, return the specification type in the third column of <emu-xref href="#table-temporal-unsigned-rounding-modes"></emu-xref> where the first column is _roundingMode_ and the second column is "negative".
669+
1. Else, return the specification type in the third column of <emu-xref href="#table-temporal-unsigned-rounding-modes"></emu-xref> where the first column is _roundingMode_ and the second column is "positive".
660670
</emu-alg>
671+
<emu-note type="editor">
672+
<p>This operation is intended to be the same one as in the <a href="https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/diff.html#sec-getunsignedroundingmode">Intl.NumberFormat v3</a> proposal.</p>
673+
</emu-note>
674+
<emu-table id="table-temporal-unsigned-rounding-modes">
675+
<emu-caption>Conversion from rounding mode to unsigned rounding mode</emu-caption>
676+
<table class="real-table">
677+
<thead>
678+
<tr>
679+
<th>Identifier</th>
680+
<th>Sign</th>
681+
<th>Unsigned Rounding Mode</th>
682+
</tr>
683+
</thead>
684+
<tr>
685+
<td rowspan="2">*"ceil"*</td>
686+
<td>positive</td>
687+
<td>~infinity~</td>
688+
</tr>
689+
<tr>
690+
<td>negative</td>
691+
<td>~zero~</td>
692+
</tr>
693+
<tr>
694+
<td rowspan="2">*"floor"*</td>
695+
<td>positive</td>
696+
<td>~zero~</td>
697+
</tr>
698+
<tr>
699+
<td>negative</td>
700+
<td>~infinity~</td>
701+
</tr>
702+
<tr>
703+
<td rowspan="2">*"expand"*</td>
704+
<td>positive</td>
705+
<td>~infinity~</td>
706+
</tr>
707+
<tr>
708+
<td>negative</td>
709+
<td>~infinity~</td>
710+
</tr>
711+
<tr>
712+
<td rowspan="2">*"trunc"*</td>
713+
<td>positive</td>
714+
<td>~zero~</td>
715+
</tr>
716+
<tr>
717+
<td>negative</td>
718+
<td>~zero~</td>
719+
</tr>
720+
<tr>
721+
<td rowspan="2">*"halfCeil"*</td>
722+
<td>positive</td>
723+
<td>~half-infinity~</td>
724+
</tr>
725+
<tr>
726+
<td>negative</td>
727+
<td>~half-zero~</td>
728+
</tr>
729+
<tr>
730+
<td rowspan="2">*"halfFloor"*</td>
731+
<td>positive</td>
732+
<td>~half-zero~</td>
733+
</tr>
734+
<tr>
735+
<td>negative</td>
736+
<td>~half-infinity~</td>
737+
</tr>
738+
<tr>
739+
<td rowspan="2">*"halfExpand"*</td>
740+
<td>positive</td>
741+
<td>~half-infinity~</td>
742+
</tr>
743+
<tr>
744+
<td>negative</td>
745+
<td>~half-infinity~</td>
746+
</tr>
747+
<tr>
748+
<td rowspan="2">*"halfTrunc"*</td>
749+
<td>positive</td>
750+
<td>~half-zero~</td>
751+
</tr>
752+
<tr>
753+
<td>negative</td>
754+
<td>~half-zero~</td>
755+
</tr>
756+
<tr>
757+
<td rowspan="2">*"halfEven"*</td>
758+
<td>positive</td>
759+
<td>~half-even~</td>
760+
</tr>
761+
<tr>
762+
<td>negative</td>
763+
<td>~half-even~</td>
764+
</tr>
765+
</table>
766+
</emu-table>
661767
</emu-clause>
662768

663-
<emu-clause id="sec-temporal-roundnumbertoincrement" aoid="RoundNumberToIncrement">
664-
<h1>RoundNumberToIncrement ( _x_, _increment_, _roundingMode_ )</h1>
665-
<p>
666-
The abstract operation RoundNumberToIncrement rounds the mathematical value _x_ to the nearest multiple of the integer _increment_.
667-
It rounds up or down according to _roundingMode_.
668-
</p>
769+
<emu-clause id="sec-temporal-applyunsignedroundingmode" type="abstract operation">
770+
<h1>
771+
ApplyUnsignedRoundingMode (
772+
_x_: a mathematical value,
773+
_r1_: a mathematical value,
774+
_r2_: a mathematical value,
775+
_unsignedRoundingMode_: ~zero~, ~infinity~, ~half-zero~, ~half-infinity~, ~half-even~, or *undefined*,
776+
): a mathematical value
777+
</h1>
778+
<dl class="header">
779+
<dt>description</dt>
780+
<dd>
781+
It considers _x_, bracketed below by _r1_ and above by _r2_, and returns either _r1_ or _r2_ according to _unsignedRoundingMode_.
782+
</dd>
783+
</dl>
784+
<emu-alg>
785+
1. If _x_ is equal to _r1_, return _r1_.
786+
1. Assert: _r1_ &lt; _x_ &lt; _r2_.
787+
1. Assert: _unsignedRoundingMode_ is not *undefined*.
788+
1. If _unsignedRoundingMode_ is ~zero~, return _r1_.
789+
1. If _unsignedRoundingMode_ is ~infinity~, return _r2_.
790+
1. Let _d1_ be <emu-eqn>_x__r1_</emu-eqn>.
791+
1. Let _d2_ be <emu-eqn>_r2__x_</emu-eqn>.
792+
1. If _d1_ &lt; _d2_, return _r1_.
793+
1. If _d2_ &lt; _d1_, return _r2_.
794+
1. Assert: _d1_ is equal to _d2_.
795+
1. If _unsignedRoundingMode_ is ~half-zero~, return _r1_.
796+
1. If _unsignedRoundingMode_ is ~half-infinity~, return _r2_.
797+
1. Assert: _unsignedRoundingMode_ is ~half-even~.
798+
1. Let _cardinality_ be <emu-eqn>(_r1_ / (_r2__r1_)) modulo 2</emu-eqn>.
799+
1. If _cardinality_ is 0, return _r1_.
800+
1. Return _r2_.
801+
</emu-alg>
669802
<emu-note type="editor">
670-
<p>
671-
The rounding modes accepted by this abstract operation are intended to be the same as whatever is eventually standardized in the <a href="https://github.com/tc39/proposal-intl-numberformat-v3">Intl.NumberFormat V3</a> proposal.
672-
</p>
803+
<p>This operation is intended to be the same one as in the <a href="https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/diff.html#sec-applyunsignedroundingmode">Intl.NumberFormat v3</a> proposal.</p>
673804
</emu-note>
805+
</emu-clause>
806+
807+
<emu-clause id="sec-temporal-roundnumbertoincrement" type="abstract operation">
808+
<h1>
809+
RoundNumberToIncrement (
810+
_x_: a mathematical value,
811+
_increment_: an integer,
812+
_roundingMode_: *"ceil"*, *"floor"*, *"trunc"*, or *"halfExpand"*,
813+
): an integer
814+
</h1>
815+
<dl class="header">
816+
<dt>description</dt>
817+
<dd>It rounds _x_ to the nearest multiple of _increment_, up or down according to _roundingMode_.</dd>
818+
</dl>
674819
<emu-alg>
675-
1. Assert: _x_ and _increment_ are mathematical values.
676-
1. Assert: _roundingMode_ is *"ceil"*, *"floor"*, *"trunc"*, or *"halfExpand"*.
677820
1. Let _quotient_ be _x_ / _increment_.
678-
1. If _roundingMode_ is *"ceil"*, then
679-
1. Let _rounded_ be -floor(-_quotient_).
680-
1. Else if _roundingMode_ is *"floor"*, then
681-
1. Let _rounded_ be floor(_quotient_).
682-
1. Else if _roundingMode_ is *"trunc"*, then
683-
1. Let _rounded_ be RoundTowardsZero(_quotient_).
821+
1. If _quotient_ &lt; 0, then
822+
1. Let _isNegative_ be *true*.
823+
1. Set _quotient_ to -_quotient_.
684824
1. Else,
685-
1. Let _rounded_ be ! RoundHalfAwayFromZero(_quotient_).
825+
1. Let _isNegative_ be *false*.
826+
1. Let _unsignedRoundingMode_ be GetUnsignedRoundingMode(_roundingMode_, _isNegative_).
827+
1. Let _r1_ be the largest integer such that _r1__quotient_.
828+
1. Let _r2_ be the smallest integer such that _r2_ &gt; _quotient_.
829+
1. Let _rounded_ be ApplyUnsignedRoundingMode(_quotient_, _r1_, _r2_, _unsignedRoundingMode_).
830+
1. If _isNegative_ is *true*, set _rounded_ to -_rounded_.
686831
1. Return _rounded_ &times; _increment_.
687832
</emu-alg>
833+
<emu-note type="editor">
834+
<p>
835+
The rounding modes accepted by this abstract operation are intended to be the same as whatever is eventually standardized in the <a href="https://github.com/tc39/proposal-intl-numberformat-v3">Intl.NumberFormat V3</a> proposal.
836+
</p>
837+
</emu-note>
688838
</emu-clause>
689839

690840
<emu-clause id="sec-temporal-iso8601grammar">

spec/duration.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,7 +1621,7 @@ <h1>
16211621
1. Let _moveResult_ be ? MoveRelativeDate(_calendar_, _relativeTo_, _oneYear_).
16221622
1. Let _oneYearDays_ be _moveResult_.[[Days]].
16231623
1. Let _fractionalYears_ be _years_ + _days_ / abs(_oneYearDays_).
1624-
1. Set _years_ to ! RoundNumberToIncrement(_fractionalYears_, _increment_, _roundingMode_).
1624+
1. Set _years_ to RoundNumberToIncrement(_fractionalYears_, _increment_, _roundingMode_).
16251625
1. Set _remainder_ to _fractionalYears_ - _years_.
16261626
1. Set _months_, _weeks_, and _days_ to 0.
16271627
1. Else if _unit_ is *"month"*, then
@@ -1645,7 +1645,7 @@ <h1>
16451645
1. Set _relativeTo_ to _moveResult_.[[RelativeTo]].
16461646
1. Set _oneMonthDays_ to _moveResult_.[[Days]].
16471647
1. Let _fractionalMonths_ be _months_ + _days_ / abs(_oneMonthDays_).
1648-
1. Set _months_ to ! RoundNumberToIncrement(_fractionalMonths_, _increment_, _roundingMode_).
1648+
1. Set _months_ to RoundNumberToIncrement(_fractionalMonths_, _increment_, _roundingMode_).
16491649
1. Set _remainder_ to _fractionalMonths_ - _months_.
16501650
1. Set _weeks_ and _days_ to 0.
16511651
1. Else if _unit_ is *"week"*, then
@@ -1661,41 +1661,41 @@ <h1>
16611661
1. Set _relativeTo_ to _moveResult_.[[RelativeTo]].
16621662
1. Set _oneWeekDays_ to _moveResult_.[[Days]].
16631663
1. Let _fractionalWeeks_ be _weeks_ + _days_ / abs(_oneWeekDays_).
1664-
1. Set _weeks_ to ! RoundNumberToIncrement(_fractionalWeeks_, _increment_, _roundingMode_).
1664+
1. Set _weeks_ to RoundNumberToIncrement(_fractionalWeeks_, _increment_, _roundingMode_).
16651665
1. Set _remainder_ to _fractionalWeeks_ - _weeks_.
16661666
1. Set _days_ to 0.
16671667
1. Else if _unit_ is *"day"*, then
16681668
1. Let _fractionalDays_ be _days_.
1669-
1. Set _days_ to ! RoundNumberToIncrement(_days_, _increment_, _roundingMode_).
1669+
1. Set _days_ to RoundNumberToIncrement(_days_, _increment_, _roundingMode_).
16701670
1. Set _remainder_ to _fractionalDays_ - _days_.
16711671
1. Else if _unit_ is *"hour"*, then
16721672
1. Let _fractionalHours_ be (_fractionalSeconds_ / 60 + _minutes_) / 60 + _hours_.
1673-
1. Set _hours_ to ! RoundNumberToIncrement(_fractionalHours_, _increment_, _roundingMode_).
1673+
1. Set _hours_ to RoundNumberToIncrement(_fractionalHours_, _increment_, _roundingMode_).
16741674
1. Set _remainder_ to _fractionalHours_ - _hours_.
16751675
1. Set _minutes_, _seconds_, _milliseconds_, _microseconds_, and _nanoseconds_ to 0.
16761676
1. Else if _unit_ is *"minute"*, then
16771677
1. Let _fractionalMinutes_ be _fractionalSeconds_ / 60 + _minutes_.
1678-
1. Set _minutes_ to ! RoundNumberToIncrement(_fractionalMinutes_, _increment_, _roundingMode_).
1678+
1. Set _minutes_ to RoundNumberToIncrement(_fractionalMinutes_, _increment_, _roundingMode_).
16791679
1. Set _remainder_ to _fractionalMinutes_ - _minutes_.
16801680
1. Set _seconds_, _milliseconds_, _microseconds_, and _nanoseconds_ to 0.
16811681
1. Else if _unit_ is *"second"*, then
1682-
1. Set _seconds_ to ! RoundNumberToIncrement(_fractionalSeconds_, _increment_, _roundingMode_).
1682+
1. Set _seconds_ to RoundNumberToIncrement(_fractionalSeconds_, _increment_, _roundingMode_).
16831683
1. Set _remainder_ to _fractionalSeconds_ - _seconds_.
16841684
1. Set _milliseconds_, _microseconds_, and _nanoseconds_ to 0.
16851685
1. Else if _unit_ is *"millisecond"*, then
16861686
1. Let _fractionalMilliseconds_ be _nanoseconds_ &times; 10<sup>-6</sup> + _microseconds_ &times; 10<sup>-3</sup> + _milliseconds_.
1687-
1. Set _milliseconds_ to ! RoundNumberToIncrement(_fractionalMilliseconds_, _increment_, _roundingMode_).
1687+
1. Set _milliseconds_ to RoundNumberToIncrement(_fractionalMilliseconds_, _increment_, _roundingMode_).
16881688
1. Set _remainder_ to _fractionalMilliseconds_ - _milliseconds_.
16891689
1. Set _microseconds_ and _nanoseconds_ to 0.
16901690
1. Else if _unit_ is *"microsecond"*, then
16911691
1. Let _fractionalMicroseconds_ be _nanoseconds_ &times; 10<sup>-3</sup> + _microseconds_.
1692-
1. Set _microseconds_ to ! RoundNumberToIncrement(_fractionalMicroseconds_, _increment_, _roundingMode_).
1692+
1. Set _microseconds_ to RoundNumberToIncrement(_fractionalMicroseconds_, _increment_, _roundingMode_).
16931693
1. Set _remainder_ to _fractionalMicroseconds_ - _microseconds_.
16941694
1. Set _nanoseconds_ to 0.
16951695
1. Else,
16961696
1. Assert: _unit_ is *"nanosecond"*.
16971697
1. Set _remainder_ to _nanoseconds_.
1698-
1. Set _nanoseconds_ to ! RoundNumberToIncrement(_nanoseconds_, _increment_, _roundingMode_).
1698+
1. Set _nanoseconds_ to RoundNumberToIncrement(_nanoseconds_, _increment_, _roundingMode_).
16991699
1. Set _remainder_ to _remainder_ - _nanoseconds_.
17001700
1. Let _duration_ be ! CreateDurationRecord(_years_, _months_, _weeks_, _days_, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_).
17011701
1. Return the Record {

spec/instant.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ <h1>RoundTemporalInstant ( _ns_, _increment_, _unit_, _roundingMode_ )</h1>
615615
1. Else,
616616
1. Assert: _unit_ is *"nanosecond"*.
617617
1. Let _incrementNs_ be _increment_.
618-
1. Return ! RoundNumberToIncrement(ℝ(_ns_), _incrementNs_, _roundingMode_).
618+
1. Return RoundNumberToIncrement(ℝ(_ns_), _incrementNs_, _roundingMode_).
619619
</emu-alg>
620620
</emu-clause>
621621

spec/plaintime.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ <h1>RoundTime ( _hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanos
909909
1. Else,
910910
1. Assert: _unit_ is *"nanosecond"*.
911911
1. Let _quantity_ be _nanosecond_.
912-
1. Let _result_ be ! RoundNumberToIncrement(_quantity_, _increment_, _roundingMode_).
912+
1. Let _result_ be RoundNumberToIncrement(_quantity_, _increment_, _roundingMode_).
913913
1. If _unit_ is *"day"*, then
914914
1. Return the Record {
915915
[[Days]]: _result_,

spec/timezone.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ <h1>FormatISOTimeZoneOffsetString ( _offsetNanoseconds_ )</h1>
597597
</p>
598598
<emu-alg>
599599
1. Assert: _offsetNanoseconds_ is an integer.
600-
1. Set _offsetNanoseconds_ to ! RoundNumberToIncrement(_offsetNanoseconds_, 60 &times; 10<sup>9</sup>, *"halfExpand"*).
600+
1. Set _offsetNanoseconds_ to RoundNumberToIncrement(_offsetNanoseconds_, 60 &times; 10<sup>9</sup>, *"halfExpand"*).
601601
1. If _offsetNanoseconds_ &ge; 0, let _sign_ be *"+"*; otherwise, let _sign_ be *"-"*.
602602
1. Set _offsetNanoseconds_ to abs(_offsetNanoseconds_).
603603
1. Let _minutes_ be _offsetNanoseconds_ / (60 &times; 10<sup>9</sup>) modulo 60.

spec/zoneddatetime.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ <h1>
10731073
1. If _candidateNanoseconds_ = _offsetNanoseconds_, then
10741074
1. Return _candidate_.[[Nanoseconds]].
10751075
1. If _matchBehaviour_ is ~match minutes~, then
1076-
1. Let _roundedCandidateNanoseconds_ be ! RoundNumberToIncrement(_candidateNanoseconds_, 60 &times; 10<sup>9</sup>, *"halfExpand"*).
1076+
1. Let _roundedCandidateNanoseconds_ be RoundNumberToIncrement(_candidateNanoseconds_, 60 &times; 10<sup>9</sup>, *"halfExpand"*).
10771077
1. If _roundedCandidateNanoseconds_ = _offsetNanoseconds_, then
10781078
1. Return _candidate_.[[Nanoseconds]].
10791079
1. If _offsetOption_ is *"reject"*, throw a *RangeError* exception.

0 commit comments

Comments
 (0)