@formatjs/ecma402-abstract 2.2.5 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/262.d.ts +5 -4
  2. package/262.js +13 -17
  3. package/CanonicalizeLocaleList.d.ts +1 -1
  4. package/IsSanctionedSimpleUnitIdentifier.d.ts +1 -1
  5. package/NumberFormat/ApplyUnsignedRoundingMode.d.ts +2 -1
  6. package/NumberFormat/ApplyUnsignedRoundingMode.js +11 -16
  7. package/NumberFormat/ComputeExponent.d.ts +2 -1
  8. package/NumberFormat/ComputeExponent.js +13 -13
  9. package/NumberFormat/ComputeExponentForMagnitude.d.ts +2 -1
  10. package/NumberFormat/ComputeExponentForMagnitude.js +12 -3
  11. package/NumberFormat/FormatNumericRange.d.ts +2 -1
  12. package/NumberFormat/FormatNumericRangeToParts.d.ts +2 -1
  13. package/NumberFormat/FormatNumericToParts.d.ts +2 -1
  14. package/NumberFormat/FormatNumericToParts.js +1 -1
  15. package/NumberFormat/FormatNumericToString.d.ts +3 -2
  16. package/NumberFormat/FormatNumericToString.js +56 -14
  17. package/NumberFormat/InitializeNumberFormat.js +7 -36
  18. package/NumberFormat/PartitionNumberPattern.d.ts +4 -3
  19. package/NumberFormat/PartitionNumberPattern.js +25 -18
  20. package/NumberFormat/PartitionNumberRangePattern.d.ts +2 -1
  21. package/NumberFormat/PartitionNumberRangePattern.js +2 -3
  22. package/NumberFormat/SetNumberFormatDigitOptions.js +53 -24
  23. package/NumberFormat/ToRawFixed.d.ts +3 -2
  24. package/NumberFormat/ToRawFixed.js +55 -18
  25. package/NumberFormat/ToRawPrecision.d.ts +3 -2
  26. package/NumberFormat/ToRawPrecision.js +75 -42
  27. package/NumberFormat/format_to_parts.d.ts +5 -2
  28. package/NumberFormat/format_to_parts.js +35 -20
  29. package/constants.d.ts +4 -0
  30. package/constants.js +8 -0
  31. package/index.d.ts +2 -1
  32. package/index.js +3 -2
  33. package/lib/262.d.ts +5 -4
  34. package/lib/262.js +13 -17
  35. package/lib/CanonicalizeLocaleList.d.ts +1 -1
  36. package/lib/IsSanctionedSimpleUnitIdentifier.d.ts +1 -1
  37. package/lib/NumberFormat/ApplyUnsignedRoundingMode.d.ts +2 -1
  38. package/lib/NumberFormat/ApplyUnsignedRoundingMode.js +11 -16
  39. package/lib/NumberFormat/ComputeExponent.d.ts +2 -1
  40. package/lib/NumberFormat/ComputeExponent.js +13 -13
  41. package/lib/NumberFormat/ComputeExponentForMagnitude.d.ts +2 -1
  42. package/lib/NumberFormat/ComputeExponentForMagnitude.js +11 -3
  43. package/lib/NumberFormat/FormatNumericRange.d.ts +2 -1
  44. package/lib/NumberFormat/FormatNumericRangeToParts.d.ts +2 -1
  45. package/lib/NumberFormat/FormatNumericToParts.d.ts +2 -1
  46. package/lib/NumberFormat/FormatNumericToParts.js +1 -1
  47. package/lib/NumberFormat/FormatNumericToString.d.ts +3 -2
  48. package/lib/NumberFormat/FormatNumericToString.js +57 -15
  49. package/lib/NumberFormat/InitializeNumberFormat.js +7 -36
  50. package/lib/NumberFormat/PartitionNumberPattern.d.ts +4 -3
  51. package/lib/NumberFormat/PartitionNumberPattern.js +25 -18
  52. package/lib/NumberFormat/PartitionNumberRangePattern.d.ts +2 -1
  53. package/lib/NumberFormat/PartitionNumberRangePattern.js +2 -3
  54. package/lib/NumberFormat/SetNumberFormatDigitOptions.js +53 -24
  55. package/lib/NumberFormat/ToRawFixed.d.ts +3 -2
  56. package/lib/NumberFormat/ToRawFixed.js +54 -18
  57. package/lib/NumberFormat/ToRawPrecision.d.ts +3 -2
  58. package/lib/NumberFormat/ToRawPrecision.js +75 -43
  59. package/lib/NumberFormat/format_to_parts.d.ts +5 -2
  60. package/lib/NumberFormat/format_to_parts.js +34 -20
  61. package/lib/constants.d.ts +4 -0
  62. package/lib/constants.js +4 -0
  63. package/lib/index.d.ts +2 -1
  64. package/lib/index.js +2 -1
  65. package/lib/types/number.d.ts +16 -9
  66. package/lib/utils.d.ts +0 -5
  67. package/lib/utils.js +0 -9
  68. package/package.json +4 -3
  69. package/types/number.d.ts +16 -9
  70. package/utils.d.ts +0 -5
  71. package/utils.js +0 -10
@@ -1,41 +1,83 @@
1
- import { SameValue } from '../262';
2
- import { ToRawPrecision } from './ToRawPrecision';
3
- import { repeat } from '../utils';
1
+ import { NEGATIVE_ZERO, ZERO } from '../constants';
2
+ import { invariant, repeat } from '../utils';
3
+ import { GetUnsignedRoundingMode } from './GetUnsignedRoundingMode';
4
4
  import { ToRawFixed } from './ToRawFixed';
5
+ import { ToRawPrecision } from './ToRawPrecision';
5
6
  /**
6
7
  * https://tc39.es/ecma402/#sec-formatnumberstring
7
8
  */
8
9
  export function FormatNumericToString(intlObject, x) {
9
- var isNegative = x < 0 || SameValue(x, -0);
10
- if (isNegative) {
11
- x = -x;
10
+ var sign;
11
+ // -0
12
+ if (x.isZero() && x.isNegative()) {
13
+ sign = 'negative';
14
+ x = ZERO;
15
+ }
16
+ else {
17
+ invariant(x.isFinite(), 'NumberFormatDigitInternalSlots value is not finite');
18
+ if (x.lessThan(0)) {
19
+ sign = 'negative';
20
+ }
21
+ else {
22
+ sign = 'positive';
23
+ }
24
+ if (sign === 'negative') {
25
+ x = x.negated();
26
+ }
12
27
  }
13
28
  var result;
14
- var rourndingType = intlObject.roundingType;
15
- switch (rourndingType) {
29
+ var roundingType = intlObject.roundingType;
30
+ var unsignedRoundingMode = GetUnsignedRoundingMode(intlObject.roundingMode, sign === 'negative');
31
+ switch (roundingType) {
16
32
  case 'significantDigits':
17
- result = ToRawPrecision(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits);
33
+ result = ToRawPrecision(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits, unsignedRoundingMode);
18
34
  break;
19
35
  case 'fractionDigits':
20
- result = ToRawFixed(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits);
36
+ result = ToRawFixed(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits, intlObject.roundingIncrement, unsignedRoundingMode);
21
37
  break;
22
38
  default:
23
- result = ToRawPrecision(x, 1, 2);
24
- if (result.integerDigitsCount > 1) {
25
- result = ToRawFixed(x, 0, 0);
39
+ var sResult = ToRawPrecision(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits, unsignedRoundingMode);
40
+ var fResult = ToRawFixed(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits, intlObject.roundingIncrement, unsignedRoundingMode);
41
+ if (intlObject.roundingType === 'morePrecision') {
42
+ if (sResult.roundingMagnitude <= fResult.roundingMagnitude) {
43
+ result = sResult;
44
+ }
45
+ else {
46
+ result = fResult;
47
+ }
48
+ }
49
+ else {
50
+ invariant(intlObject.roundingType === 'lessPrecision', 'Invalid roundingType');
51
+ if (sResult.roundingMagnitude <= fResult.roundingMagnitude) {
52
+ result = fResult;
53
+ }
54
+ else {
55
+ result = sResult;
56
+ }
26
57
  }
27
58
  break;
28
59
  }
29
60
  x = result.roundedNumber;
30
61
  var string = result.formattedString;
62
+ if (intlObject.trailingZeroDisplay === 'stripIfInteger' && x.isInteger()) {
63
+ var i = string.indexOf('.');
64
+ if (i > -1) {
65
+ string = string.slice(0, i);
66
+ }
67
+ }
31
68
  var int = result.integerDigitsCount;
32
69
  var minInteger = intlObject.minimumIntegerDigits;
33
70
  if (int < minInteger) {
34
71
  var forwardZeros = repeat('0', minInteger - int);
35
72
  string = forwardZeros + string;
36
73
  }
37
- if (isNegative) {
38
- x = -x;
74
+ if (sign === 'negative') {
75
+ if (x.isZero()) {
76
+ x = NEGATIVE_ZERO;
77
+ }
78
+ else {
79
+ x = x.negated();
80
+ }
39
81
  }
40
82
  return { roundedNumber: x, formattedString: string };
41
83
  }
@@ -1,22 +1,17 @@
1
1
  import { ResolveLocale } from '@formatjs/intl-localematcher';
2
2
  import { CanonicalizeLocaleList } from '../CanonicalizeLocaleList';
3
3
  import { CoerceOptionsToObject } from '../CoerceOptionsToObject';
4
- import { GetNumberOption } from '../GetNumberOption';
5
4
  import { GetOption } from '../GetOption';
6
5
  import { GetStringOrBooleanOption } from '../GetStringOrBooleanOption';
7
6
  import { invariant } from '../utils';
8
7
  import { CurrencyDigits } from './CurrencyDigits';
9
8
  import { SetNumberFormatDigitOptions } from './SetNumberFormatDigitOptions';
10
9
  import { SetNumberFormatUnitOptions } from './SetNumberFormatUnitOptions';
11
- var VALID_ROUND_INCREMENT_VALUES = [
12
- 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000,
13
- ];
14
10
  /**
15
11
  * https://tc39.es/ecma402/#sec-initializenumberformat
16
12
  */
17
13
  export function InitializeNumberFormat(nf, locales, opts, _a) {
18
14
  var getInternalSlots = _a.getInternalSlots, localeData = _a.localeData, availableLocales = _a.availableLocales, numberingSystemNames = _a.numberingSystemNames, getDefaultLocale = _a.getDefaultLocale, currencyDigitsData = _a.currencyDigitsData;
19
- // @ts-ignore
20
15
  var requestedLocales = CanonicalizeLocaleList(locales);
21
16
  var options = CoerceOptionsToObject(opts);
22
17
  var opt = Object.create(null);
@@ -42,9 +37,11 @@ export function InitializeNumberFormat(nf, locales, opts, _a) {
42
37
  internalSlots.dataLocaleData = dataLocaleData;
43
38
  SetNumberFormatUnitOptions(nf, options, { getInternalSlots: getInternalSlots });
44
39
  var style = internalSlots.style;
40
+ var notation = GetOption(options, 'notation', 'string', ['standard', 'scientific', 'engineering', 'compact'], 'standard');
41
+ internalSlots.notation = notation;
45
42
  var mnfdDefault;
46
43
  var mxfdDefault;
47
- if (style === 'currency') {
44
+ if (style === 'currency' && notation === 'standard') {
48
45
  var currency = internalSlots.currency;
49
46
  var cDigits = CurrencyDigits(currency, { currencyDigitsData: currencyDigitsData });
50
47
  mnfdDefault = cDigits;
@@ -54,42 +51,16 @@ export function InitializeNumberFormat(nf, locales, opts, _a) {
54
51
  mnfdDefault = 0;
55
52
  mxfdDefault = style === 'percent' ? 0 : 3;
56
53
  }
57
- var notation = GetOption(options, 'notation', 'string', ['standard', 'scientific', 'engineering', 'compact'], 'standard');
58
- internalSlots.notation = notation;
59
54
  SetNumberFormatDigitOptions(internalSlots, options, mnfdDefault, mxfdDefault, notation);
60
- var roundingIncrement = GetNumberOption(options, 'roundingIncrement', 1, 5000, 1);
61
- if (VALID_ROUND_INCREMENT_VALUES.indexOf(roundingIncrement) === -1) {
62
- throw new RangeError("Invalid rounding increment value: ".concat(roundingIncrement, ".\nValid values are ").concat(VALID_ROUND_INCREMENT_VALUES, "."));
63
- }
64
- if (roundingIncrement !== 1 &&
65
- internalSlots.roundingType !== 'fractionDigits') {
66
- throw new TypeError("For roundingIncrement > 1 only fractionDigits is a valid roundingType");
67
- }
68
- if (roundingIncrement !== 1 &&
69
- internalSlots.maximumFractionDigits !== internalSlots.minimumFractionDigits) {
70
- throw new RangeError('With roundingIncrement > 1, maximumFractionDigits and minimumFractionDigits must be equal.');
71
- }
72
- internalSlots.roundingIncrement = roundingIncrement;
73
- var trailingZeroDisplay = GetOption(options, 'trailingZeroDisplay', 'string', ['auto', 'stripIfInteger'], 'auto');
74
- internalSlots.trailingZeroDisplay = trailingZeroDisplay;
75
55
  var compactDisplay = GetOption(options, 'compactDisplay', 'string', ['short', 'long'], 'short');
76
56
  var defaultUseGrouping = 'auto';
77
57
  if (notation === 'compact') {
78
58
  internalSlots.compactDisplay = compactDisplay;
79
59
  defaultUseGrouping = 'min2';
80
60
  }
81
- internalSlots.useGrouping = GetStringOrBooleanOption(options, 'useGrouping', ['min2', 'auto', 'always'], 'always', false, defaultUseGrouping);
82
- internalSlots.signDisplay = GetOption(options, 'signDisplay', 'string', ['auto', 'never', 'always', 'exceptZero', 'negative'], 'auto');
83
- internalSlots.roundingMode = GetOption(options, 'roundingMode', 'string', [
84
- 'ceil',
85
- 'floor',
86
- 'expand',
87
- 'trunc',
88
- 'halfCeil',
89
- 'halfFloor',
90
- 'halfExpand',
91
- 'halfTrunc',
92
- 'halfEven',
93
- ], 'halfExpand');
61
+ var useGrouping = GetStringOrBooleanOption(options, 'useGrouping', ['min2', 'auto', 'always'], 'always', false, defaultUseGrouping);
62
+ internalSlots.useGrouping = useGrouping;
63
+ var signDisplay = GetOption(options, 'signDisplay', 'string', ['auto', 'never', 'always', 'exceptZero', 'negative'], 'auto');
64
+ internalSlots.signDisplay = signDisplay;
94
65
  return nf;
95
66
  }
@@ -1,7 +1,8 @@
1
- import { NumberFormatInternal } from '../types/number';
1
+ import Decimal from 'decimal.js';
2
+ import { NumberFormatInternal, NumberFormatPart } from '../types/number';
2
3
  /**
3
4
  * https://tc39.es/ecma402/#sec-formatnumberstring
4
5
  */
5
- export declare function PartitionNumberPattern(numberFormat: Intl.NumberFormat, x: number, { getInternalSlots, }: {
6
+ export declare function PartitionNumberPattern(numberFormat: Intl.NumberFormat, x: Decimal, { getInternalSlots, }: {
6
7
  getInternalSlots(nf: Intl.NumberFormat): NumberFormatInternal;
7
- }): import("..").NumberFormatPart[];
8
+ }): NumberFormatPart[];
@@ -1,7 +1,8 @@
1
- import { FormatNumericToString } from './FormatNumericToString';
2
- import { SameValue } from '../262';
1
+ import { TEN } from '../constants';
2
+ import { invariant } from '../utils';
3
3
  import { ComputeExponent } from './ComputeExponent';
4
4
  import formatToParts from './format_to_parts';
5
+ import { FormatNumericToString } from './FormatNumericToString';
5
6
  /**
6
7
  * https://tc39.es/ecma402/#sec-formatnumberstring
7
8
  */
@@ -15,26 +16,23 @@ export function PartitionNumberPattern(numberFormat, x, _a) {
15
16
  var magnitude = 0;
16
17
  var exponent = 0;
17
18
  var n;
18
- if (isNaN(x)) {
19
+ if (x.isNaN()) {
19
20
  n = symbols.nan;
20
21
  }
21
- else if (x == Number.POSITIVE_INFINITY || x == Number.NEGATIVE_INFINITY) {
22
+ else if (!x.isFinite()) {
22
23
  n = symbols.infinity;
23
24
  }
24
25
  else {
25
- if (!SameValue(x, -0)) {
26
- if (!isFinite(x)) {
27
- throw new Error('Input must be a mathematical value');
28
- }
26
+ if (!x.isZero()) {
27
+ invariant(x.isFinite(), 'Input must be a mathematical value');
29
28
  if (internalSlots.style == 'percent') {
30
- x *= 100;
29
+ x = x.times(100);
31
30
  }
32
31
  ;
33
32
  _b = ComputeExponent(numberFormat, x, {
34
33
  getInternalSlots: getInternalSlots,
35
34
  }), exponent = _b[0], magnitude = _b[1];
36
- // Preserve more precision by doing multiplication when exponent is negative.
37
- x = exponent < 0 ? x * Math.pow(10, -exponent) : x / Math.pow(10, exponent);
35
+ x = x.times(TEN.pow(-exponent));
38
36
  }
39
37
  var formatNumberResult = FormatNumericToString(internalSlots, x);
40
38
  n = formatNumberResult.formattedString;
@@ -49,7 +47,7 @@ export function PartitionNumberPattern(numberFormat, x, _a) {
49
47
  sign = 0;
50
48
  break;
51
49
  case 'auto':
52
- if (SameValue(x, 0) || x > 0 || isNaN(x)) {
50
+ if (x.isPositive() || x.isNaN()) {
53
51
  sign = 0;
54
52
  }
55
53
  else {
@@ -57,24 +55,33 @@ export function PartitionNumberPattern(numberFormat, x, _a) {
57
55
  }
58
56
  break;
59
57
  case 'always':
60
- if (SameValue(x, 0) || x > 0 || isNaN(x)) {
58
+ if (x.isPositive() || x.isNaN()) {
61
59
  sign = 1;
62
60
  }
63
61
  else {
64
62
  sign = -1;
65
63
  }
66
64
  break;
67
- default:
68
- // x === 0 -> x is 0 or x is -0
69
- if (x === 0 || isNaN(x)) {
65
+ case 'exceptZero':
66
+ if (x.isZero()) {
70
67
  sign = 0;
71
68
  }
72
- else if (x > 0) {
73
- sign = 1;
69
+ else if (x.isNegative()) {
70
+ sign = -1;
74
71
  }
75
72
  else {
73
+ sign = 1;
74
+ }
75
+ break;
76
+ default:
77
+ invariant(signDisplay === 'negative', 'signDisplay must be "negative"');
78
+ if (x.isNegative() && !x.isZero()) {
76
79
  sign = -1;
77
80
  }
81
+ else {
82
+ sign = 0;
83
+ }
84
+ break;
78
85
  }
79
86
  return formatToParts({ roundedNumber: x, formattedString: n, exponent: exponent, magnitude: magnitude, sign: sign }, internalSlots.dataLocaleData, pl, internalSlots);
80
87
  }
@@ -1,7 +1,8 @@
1
+ import Decimal from 'decimal.js';
1
2
  import { NumberFormatInternal, NumberFormatPart } from '../types/number';
2
3
  /**
3
4
  * https://tc39.es/ecma402/#sec-partitionnumberrangepattern
4
5
  */
5
- export declare function PartitionNumberRangePattern(numberFormat: Intl.NumberFormat, x: number, y: number, { getInternalSlots, }: {
6
+ export declare function PartitionNumberRangePattern(numberFormat: Intl.NumberFormat, x: Decimal, y: Decimal, { getInternalSlots, }: {
6
7
  getInternalSlots(nf: Intl.NumberFormat): NumberFormatInternal;
7
8
  }): NumberFormatPart[];
@@ -1,3 +1,4 @@
1
+ import { invariant } from '../utils';
1
2
  import { CollapseNumberRange } from './CollapseNumberRange';
2
3
  import { FormatApproximately } from './FormatApproximately';
3
4
  import { PartitionNumberPattern } from './PartitionNumberPattern';
@@ -6,9 +7,7 @@ import { PartitionNumberPattern } from './PartitionNumberPattern';
6
7
  */
7
8
  export function PartitionNumberRangePattern(numberFormat, x, y, _a) {
8
9
  var getInternalSlots = _a.getInternalSlots;
9
- if (isNaN(x) || isNaN(y)) {
10
- throw new RangeError('Input must be a number');
11
- }
10
+ invariant(!x.isNaN() && !y.isNaN(), 'Input must be a number');
12
11
  var result = [];
13
12
  var xResult = PartitionNumberPattern(numberFormat, x, { getInternalSlots: getInternalSlots });
14
13
  var yResult = PartitionNumberPattern(numberFormat, y, { getInternalSlots: getInternalSlots });
@@ -1,6 +1,10 @@
1
1
  import { DefaultNumberOption } from '../DefaultNumberOption';
2
2
  import { GetNumberOption } from '../GetNumberOption';
3
3
  import { GetOption } from '../GetOption';
4
+ import { invariant } from '../utils';
5
+ var VALID_ROUNDING_INCREMENTS = new Set([
6
+ 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000,
7
+ ]);
4
8
  /**
5
9
  * https://tc39.es/ecma402/#sec-setnfdigitoptions
6
10
  */
@@ -11,7 +15,27 @@ export function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mx
11
15
  var mnsd = opts.minimumSignificantDigits;
12
16
  var mxsd = opts.maximumSignificantDigits;
13
17
  internalSlots.minimumIntegerDigits = mnid;
18
+ var roundingIncrement = GetNumberOption(opts, 'roundingIncrement', 1, 5000, 1);
19
+ invariant(VALID_ROUNDING_INCREMENTS.has(roundingIncrement), "Invalid rounding increment value: ".concat(roundingIncrement, ".\nValid values are ").concat(Array.from(VALID_ROUNDING_INCREMENTS).join(', '), "."));
20
+ var roundingMode = GetOption(opts, 'roundingMode', 'string', [
21
+ 'ceil',
22
+ 'floor',
23
+ 'expand',
24
+ 'trunc',
25
+ 'halfCeil',
26
+ 'halfFloor',
27
+ 'halfExpand',
28
+ 'halfTrunc',
29
+ 'halfEven',
30
+ ], 'halfExpand');
14
31
  var roundingPriority = GetOption(opts, 'roundingPriority', 'string', ['auto', 'morePrecision', 'lessPrecision'], 'auto');
32
+ var trailingZeroDisplay = GetOption(opts, 'trailingZeroDisplay', 'string', ['auto', 'stripIfInteger'], 'auto');
33
+ if (roundingIncrement !== 1) {
34
+ mxfdDefault = mnfdDefault;
35
+ }
36
+ internalSlots.roundingIncrement = roundingIncrement;
37
+ internalSlots.roundingMode = roundingMode;
38
+ internalSlots.trailingZeroDisplay = trailingZeroDisplay;
15
39
  var hasSd = mnsd !== undefined || mxsd !== undefined;
16
40
  var hasFd = mnfd !== undefined || mxfd !== undefined;
17
41
  var needSd = true;
@@ -24,10 +48,8 @@ export function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mx
24
48
  }
25
49
  if (needSd) {
26
50
  if (hasSd) {
27
- mnsd = DefaultNumberOption(mnsd, 1, 21, 1);
28
- mxsd = DefaultNumberOption(mxsd, mnsd, 21, 21);
29
- internalSlots.minimumSignificantDigits = mnsd;
30
- internalSlots.maximumSignificantDigits = mxsd;
51
+ internalSlots.minimumSignificantDigits = DefaultNumberOption(mnsd, 1, 21, 1);
52
+ internalSlots.maximumSignificantDigits = DefaultNumberOption(mxsd, internalSlots.minimumSignificantDigits, 21, 21);
31
53
  }
32
54
  else {
33
55
  internalSlots.minimumSignificantDigits = 1;
@@ -36,11 +58,10 @@ export function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mx
36
58
  }
37
59
  if (needFd) {
38
60
  if (hasFd) {
39
- mnfd = DefaultNumberOption(mnfd, 0, 20, undefined);
40
- mxfd = DefaultNumberOption(mxfd, 0, 20, undefined);
61
+ mnfd = DefaultNumberOption(mnfd, 0, 100, undefined);
62
+ mxfd = DefaultNumberOption(mxfd, 0, 100, undefined);
41
63
  if (mnfd === undefined) {
42
- // @ts-expect-error
43
- mnfd = Math.min(mnfdDefault, mxfd);
64
+ mnfd = Math.min(mnfdDefault, mxfd !== null && mxfd !== void 0 ? mxfd : 0);
44
65
  }
45
66
  else if (mxfd === undefined) {
46
67
  mxfd = Math.max(mxfdDefault, mnfd);
@@ -56,25 +77,33 @@ export function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mx
56
77
  internalSlots.maximumFractionDigits = mxfdDefault;
57
78
  }
58
79
  }
59
- if (needSd || needFd) {
60
- if (roundingPriority === 'morePrecision') {
61
- internalSlots.roundingType = 'morePrecision';
62
- }
63
- else if (roundingPriority === 'lessPrecision') {
64
- internalSlots.roundingType = 'lessPrecision';
65
- }
66
- else if (hasSd) {
67
- internalSlots.roundingType = 'significantDigits';
68
- }
69
- else {
70
- internalSlots.roundingType = 'fractionDigits';
71
- }
72
- }
73
- else {
74
- internalSlots.roundingType = 'morePrecision';
80
+ if (!needSd && !needFd) {
75
81
  internalSlots.minimumFractionDigits = 0;
76
82
  internalSlots.maximumFractionDigits = 0;
77
83
  internalSlots.minimumSignificantDigits = 1;
78
84
  internalSlots.maximumSignificantDigits = 2;
85
+ internalSlots.roundingType = 'morePrecision';
86
+ internalSlots.roundingPriority = 'morePrecision';
87
+ }
88
+ else if (roundingPriority === 'morePrecision') {
89
+ internalSlots.roundingType = 'morePrecision';
90
+ internalSlots.roundingPriority = 'morePrecision';
91
+ }
92
+ else if (roundingPriority === 'lessPrecision') {
93
+ internalSlots.roundingType = 'lessPrecision';
94
+ internalSlots.roundingPriority = 'lessPrecision';
95
+ }
96
+ else if (hasSd) {
97
+ internalSlots.roundingType = 'significantDigits';
98
+ internalSlots.roundingPriority = 'auto';
99
+ }
100
+ else {
101
+ internalSlots.roundingType = 'fractionDigits';
102
+ internalSlots.roundingPriority = 'auto';
103
+ }
104
+ if (roundingIncrement !== 1) {
105
+ invariant(internalSlots.roundingType === 'fractionDigits', 'Invalid roundingType');
106
+ invariant(internalSlots.maximumFractionDigits ===
107
+ internalSlots.minimumFractionDigits, 'With roundingIncrement > 1, maximumFractionDigits and minimumFractionDigits must be equal.');
79
108
  }
80
109
  }
@@ -1,4 +1,5 @@
1
- import { RawNumberFormatResult } from '../types/number';
1
+ import Decimal from 'decimal.js';
2
+ import { RawNumberFormatResult, UnsignedRoundingModeType } from '../types/number';
2
3
  /**
3
4
  * TODO: dedup with intl-pluralrules and support BigInt
4
5
  * https://tc39.es/ecma402/#sec-torawfixed
@@ -6,4 +7,4 @@ import { RawNumberFormatResult } from '../types/number';
6
7
  * @param minFraction and integer between 0 and 20
7
8
  * @param maxFraction and integer between 0 and 20
8
9
  */
9
- export declare function ToRawFixed(x: number, minFraction: number, maxFraction: number): RawNumberFormatResult;
10
+ export declare function ToRawFixed(x: Decimal, minFraction: number, maxFraction: number, roundingIncrement: number, unsignedRoundingMode: UnsignedRoundingModeType): RawNumberFormatResult;
@@ -1,4 +1,31 @@
1
+ import Decimal from 'decimal.js';
2
+ import { TEN } from '../constants';
1
3
  import { repeat } from '../utils';
4
+ import { ApplyUnsignedRoundingMode } from './ApplyUnsignedRoundingMode';
5
+ Decimal.set({
6
+ toExpPos: 100,
7
+ });
8
+ function ToRawFixedFn(n, f) {
9
+ return n.times(TEN.pow(-f));
10
+ }
11
+ function findN1R1(x, f, roundingIncrement) {
12
+ var nx = x.times(TEN.pow(f)).floor();
13
+ var n1 = nx.div(roundingIncrement).floor().times(roundingIncrement);
14
+ var r1 = ToRawFixedFn(n1, f);
15
+ return {
16
+ n1: n1,
17
+ r1: r1,
18
+ };
19
+ }
20
+ function findN2R2(x, f, roundingIncrement) {
21
+ var nx = x.times(TEN.pow(f)).ceil();
22
+ var n2 = nx.div(roundingIncrement).ceil().times(roundingIncrement);
23
+ var r2 = ToRawFixedFn(n2, f);
24
+ return {
25
+ n2: n2,
26
+ r2: r2,
27
+ };
28
+ }
2
29
  /**
3
30
  * TODO: dedup with intl-pluralrules and support BigInt
4
31
  * https://tc39.es/ecma402/#sec-torawfixed
@@ -6,34 +33,38 @@ import { repeat } from '../utils';
6
33
  * @param minFraction and integer between 0 and 20
7
34
  * @param maxFraction and integer between 0 and 20
8
35
  */
9
- export function ToRawFixed(x, minFraction, maxFraction) {
36
+ export function ToRawFixed(x, minFraction, maxFraction, roundingIncrement, unsignedRoundingMode) {
10
37
  var f = maxFraction;
11
- var n = Math.round(x * Math.pow(10, f));
12
- var xFinal = n / Math.pow(10, f);
13
- // n is a positive integer, but it is possible to be greater than 1e21.
14
- // In such case we will go the slow path.
15
- // See also: https://tc39.es/ecma262/#sec-numeric-types-number-tostring
38
+ var _a = findN1R1(x, f, roundingIncrement), n1 = _a.n1, r1 = _a.r1;
39
+ var _b = findN2R2(x, f, roundingIncrement), n2 = _b.n2, r2 = _b.r2;
40
+ var r = ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode);
41
+ var n, xFinal;
16
42
  var m;
17
- if (n < 1e21) {
18
- m = n.toString();
43
+ if (r.eq(r1)) {
44
+ n = n1;
45
+ xFinal = r1;
46
+ }
47
+ else {
48
+ n = n2;
49
+ xFinal = r2;
50
+ }
51
+ if (n.isZero()) {
52
+ m = '0';
19
53
  }
20
54
  else {
21
55
  m = n.toString();
22
- var _a = m.split('e'), mantissa = _a[0], exponent = _a[1];
23
- m = mantissa.replace('.', '');
24
- m = m + repeat('0', Math.max(+exponent - m.length + 1, 0));
25
56
  }
26
57
  var int;
27
58
  if (f !== 0) {
28
59
  var k = m.length;
29
60
  if (k <= f) {
30
- var z = repeat('0', f + 1 - k);
61
+ var z = repeat('0', f - k + 1);
31
62
  m = z + m;
32
63
  k = f + 1;
33
64
  }
34
65
  var a = m.slice(0, k - f);
35
- var b = m.slice(k - f);
36
- m = "".concat(a, ".").concat(b);
66
+ var b = m.slice(m.length - f);
67
+ m = a + '.' + b;
37
68
  int = a.length;
38
69
  }
39
70
  else {
@@ -41,11 +72,16 @@ export function ToRawFixed(x, minFraction, maxFraction) {
41
72
  }
42
73
  var cut = maxFraction - minFraction;
43
74
  while (cut > 0 && m[m.length - 1] === '0') {
44
- m = m.slice(0, -1);
75
+ m = m.slice(0, m.length - 1);
45
76
  cut--;
46
77
  }
47
- if (m[m.length - 1] === '.') {
48
- m = m.slice(0, -1);
78
+ if (m[m.length - 1] === '\u002e') {
79
+ m = m.slice(0, m.length - 1);
49
80
  }
50
- return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int };
81
+ return {
82
+ formattedString: m,
83
+ roundedNumber: xFinal,
84
+ integerDigitsCount: int,
85
+ roundingMagnitude: -f,
86
+ };
51
87
  }
@@ -1,2 +1,3 @@
1
- import { RawNumberFormatResult } from '../types/number';
2
- export declare function ToRawPrecision(x: number, minPrecision: number, maxPrecision: number): RawNumberFormatResult;
1
+ import Decimal from 'decimal.js';
2
+ import { RawNumberFormatResult, UnsignedRoundingModeType } from '../types/number';
3
+ export declare function ToRawPrecision(x: Decimal, minPrecision: number, maxPrecision: number, unsignedRoundingMode: UnsignedRoundingModeType): RawNumberFormatResult;