Skip to content

Commit dca3b87

Browse files
Use significant digits only on the way in and out
1 parent 3d86a93 commit dca3b87

File tree

1 file changed

+54
-62
lines changed

1 file changed

+54
-62
lines changed

spec.emu

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -262,32 +262,6 @@ location: https://github.com/tc39/proposal-amount/
262262
</emu-alg>
263263
</emu-clause>
264264

265-
<emu-clause id="sec-amount-roundtosignificantdigits" type="abstract operation">
266-
<h1>RoundToSignificantDigits (
267-
_v_: a mathematical value,
268-
_n_: a non-negative integer,
269-
optional _roundingMode_: a rounding mode
270-
): a mathematical value
271-
</h1>
272-
<dl class="header">
273-
<dt>description</dt>
274-
<dd>It computes the closest approximation to a given mathematical value that has at most the given number of significant digits, rounding (if necessary) according to the given rounding mode.</dd>
275-
</dl>
276-
<emu-alg>
277-
1. If _roundingMode_ is *undefined*, set _roundingMode_ to *"halfEven"*.
278-
1. If _v_ = 0, return 0.
279-
1. If v &lt; 0, then
280-
1. Let _reverseRoundingMode_ be ReverseRoundingMode(_roundingMode_).
281-
1. Let _d_ be RoundToSignificantDigits(–_v_, _n_, _reverseRoundingMode_).
282-
1. Return –_d_.
283-
1. Let _e_ be the unique integer such that 10<sup>_e_</sup> ≤ _v_ < 10<sup>_e_+1</sup>.
284-
1. Let _pow_ be _e_ - _n_.
285-
1. Let _m_ be _v_ × 10<sup>–_pow_</sup>.
286-
1. Let _rounded_ be ApplyRoundingModeToPositive(_m_, _roundingMode_).
287-
1. Return _rounded_ × 10<sup>_n_ + _e_</sup>.
288-
</emu-alg>
289-
</emu-clause>
290-
291265
<emu-clause id="sec-amount-rendermvwithfractiondigits" type="abstract operation">
292266
<h1>RenderAmountValueWithFractionDigits (
293267
_v_: an Intl mathematical value,
@@ -340,6 +314,46 @@ location: https://github.com/tc39/proposal-amount/
340314
</emu-alg>
341315
</emu-clause>
342316

317+
<emu-clause id="sec-amount-FractionToSignificantDigits" type="abstract operation">
318+
<h1>FractionToSignificantDigits (
319+
_value_: an Intl mathematical value,
320+
_fractionDigits_: an integer
321+
): a non-negative integer
322+
</h1>
323+
<dl class="header"></dl>
324+
<emu-alg>
325+
1. If _value_ is one of ~not-a-number~, ~positive-infinity~, or ~negative-infinity~, then
326+
1. Return 0.
327+
1. If _value_ is one of 0 or ~negative-zero~, then
328+
1. Let _integerDigitsMinusOne_ be 0.
329+
1. Else
330+
1. Let _e_ be the smallest integer such that _e_ > the base 10 logarithm of abs(_value_).
331+
1. Let _integerDigits_ be 1 + _e_.
332+
1. Assert: _integerDigits_ + _fractionDigits_ > 0.
333+
1. Return _integerDigits_ + _fractionDigits_.
334+
</emu-alg>
335+
</emu-clause>
336+
337+
<emu-clause id="sec-amount-SignificantToFractionDigits" type="abstract operation">
338+
<h1>SignificantToFractionDigits (
339+
_value_: an Intl mathematical value,
340+
_significantDigits_: an integer
341+
): an integer
342+
</h1>
343+
<dl class="header"></dl>
344+
<emu-alg>
345+
1. If _value_ is one of ~not-a-number~, ~positive-infinity~, or ~negative-infinity~, then
346+
1. Return 0.
347+
1. If _value_ is one of 0 or ~negative-zero~, then
348+
1. Let _integerDigits_ be 1.
349+
1. Else
350+
1. Let _e_ be the smallest integer such that _e_ > the base 10 logarithm of abs(_value_).
351+
1. Let _integerDigits_ be 1 + _e_.
352+
1. Assert: _significantDigits_ > 0.
353+
1. Return _significantDigits_ - _integerDigits_.
354+
</emu-alg>
355+
</emu-clause>
356+
343357
<emu-clause id="sec-amount-getamountoptions" type="abstract operation">
344358
<h1>GetAmountOptions (
345359
_opts_: an Object
@@ -389,48 +403,27 @@ location: https://github.com/tc39/proposal-amount/
389403
1. Let _parsed_ be ParseText(_toParse_, |StringNumericLiteral|).
390404
1. If _parsed_ is a List of errors, then
391405
1. Let _amountValue_ be ~not-a-number~.
392-
1. Let _numDigits_ be 0.
393406
1. Else,
394407
1. Let _intlMV_ be the StringIntlMV of _parsed_.
395408
1. Let _amountValue_ be _intlMV_[0].
396-
1. Let _numDigits_ be _intlMV_[1].
397409
1. Let _validatedOpts_ be ? GetAmountOptions(_opts_).
398-
1. Let _fractionDigits_ be _validatedOpts_.[[FractionDigits]].
399410
1. Let _roundingMode_ be _validatedOpts_.[[RoundingMode]].
411+
1. Let _fractionDigits_ be _validatedOpts_.[[FractionDigits]].
400412
1. Let _significantDigits_ be _validatedOpts_.[[SignificantDigits]].
401413
1. Let _unit_ be _validatedOpts_.[[Unit]].
402-
1. Let _O_ be OrdinaryObjectCreate(%Amount.prototype%, « [[FractionDigits]], [[SignificantDigits]], [[Unit]], [[Value]] »).
403-
1. If _amountValue_ is a mathematical value, then
404-
1. Let _roundedValue_ be _amountValue_.
405-
1. If both _significantDigits_ and _fractionDigits_ are *undefined*, then
406-
1. Set _significantDigits_ to _numDigits_.
414+
1. Let _O_ be OrdinaryObjectCreate(%Amount.prototype%, « [[FractionDigits]], [[Unit]], [[Value]] »).
415+
1. If _fractionDigits_ is *undefined*, then
416+
1. If _significantDigits_ is not *undefined*, then
417+
1. Set _fractionDigits_ to SignificantToFractionDigits(_amountValue_, _significantDigits_).
418+
1. Else if _amountValue_ is a mathematical value or ~negative-zero~, then
407419
1. Set _fractionDigits_ to the CountFractionDigits of _toParse_.
408-
1. Else if _significantDigits_ is *undefined*, then
409-
1. Set _roundedValue_ be RoundAmountValueToFractionDigits(_amountValue_, _fractionDigits_, _roundingMode_).
410-
1. Let _e_ be the smallest non-negative integer such that _roundedValue_ × 10<sup>-_e_</sup> is an integer.
411-
1. Let _scaledRoundedValue_ be _roundedValue_ × 10<sup>-_e_</sup>.
412-
1. If _scaledRoundedValue_ = 0, then
413-
1. Set _significantDigits_ to 1.
414-
1. Else,
415-
1. Let _l_ be the log-10 of abs(_scaledRoundedValue_).
416-
1. Set _significantDigits_ to floor(_l_) + 1.
417-
1. Otherwise:
418-
1. Set _roundedValue_ be RoundToSignificantDigits(_amountValue_, _significantDigits_, _roundingMode_).
419-
1. Let _digitStr_ be the unique decimal string representation of _roundedValue_ without duplicate leading zeroes.
420-
1. Set _fractionDigits_ to the CountFractionDigits of _digitStr_.
421-
1. Set _O_.[[Value]] to _roundedValue_.
422-
1. Set _O_.[[SignificantDigits]] to _significantDigits_.
423-
1. Set _O_.[[FractionDigits]] to _fractionDigits_.
424-
1. Else if _amountValue_ is ~minus-zero~, then
425-
1. Set _O_.[[Value]] to ~minus-zero~.
426-
1. Set _O_.[[SignificantDigits]] to _numDigits_.
427-
1. Assert: _numDigits_ ≥ 1.
428-
1. Set _O_.[[FractionDigits]] to _numDigits_ - 1.
429-
1. Otherwise:
420+
1. Else, set _fractionDigits_ to 0.
421+
1. Set _O_.[[FractionDigits]] to _fractionDigits_.
422+
1. If _amountValue_ is a mathematical value, then
423+
1. Set _O_.[[Value]] to RoundAmountValueToFractionDigits(_amountValue_, _fractionDigits_, _roundingMode_).
424+
1. Else
430425
1. Set _O_.[[Value]] to _amountValue_.
431-
1. Set _O_.[[SignificantDigits]] to _numDigits_..
432-
1. Set _O_.[[FractionDigits]] to 0.
433-
1. If _unit_ is not *undefined* and _amountValue_ is not ~not-a-number~, set _O_.[[Unit]] to _unit_.
426+
1. If _unit_ is not *undefined* and _amountValue_ is not ~not-a-number~~, set _O_.[[Unit]] to _unit_.
434427
1. Return _O_.
435428
</emu-alg>
436429
<emu-note>
@@ -486,15 +479,14 @@ location: https://github.com/tc39/proposal-amount/
486479
1. Let _fractionDigits_ be _processedOptions_.[[FractionDigits]].
487480
1. Let _significantDigits_ be _processedOptions_.[[SignificantDigits]].
488481
1. Let _value_ be _O_.[[Value]].
482+
1. If _significantDigits_ is not *undefined*, set _fractionDigits_ to SignificantToFractionDigits(_value_, _significantDigits_).
489483
1. If _fractionDigits_ is not *undefined*, set _value_ to RoundAmountValueToFractionDigits(_value_, _fractionDigits_).
490-
1. Else if _significantDigits_ is not *undefined*, set _value_ to RoundToSignificantDigits(_value_, _significantDigits_).
491-
1. Let _N_ be OrdinaryObjectCreate(*"%Amount.prototype%"*, « [[FractionDigits]], [[SignificantDigits]], [[Unit]], [[Value]] »).
484+
1. Let _N_ be OrdinaryObjectCreate(*"%Amount.prototype%"*, « [[FractionDigits]], [[Unit]], [[Value]] »).
492485
1. If _unit_ is not *undefined* and _O_.[[Unit]] is not *undefined*, then
493486
1. If SameValueNonNumber(_unit_, _O_.[[Unit]]) is *false*, throw a *TypeError* exception.
494487
1. Set _N_.[[Value]] to _value_.
495488
1. Set _N_.[[Unit]] to _unit_.
496489
1. Set _N_.[[FractionDigits]] to ℝ(_fractionDigits_).
497-
1. Set _N_.[[SignificantDigits]] to ℝ(_significantDigits_).
498490
1. Return _N_.
499491
</emu-alg>
500492
</emu-clause>

0 commit comments

Comments
 (0)