@formatjs/ecma402-abstract 2.2.4 → 2.3.0

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 (163) 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 +20 -15
  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 +19 -15
  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
  72. package/262.js.map +0 -1
  73. package/CanonicalizeLocaleList.js.map +0 -1
  74. package/CanonicalizeTimeZoneName.js.map +0 -1
  75. package/CoerceOptionsToObject.js.map +0 -1
  76. package/DefaultNumberOption.js.map +0 -1
  77. package/GetNumberOption.js.map +0 -1
  78. package/GetOption.js.map +0 -1
  79. package/GetOptionsObject.js.map +0 -1
  80. package/GetStringOrBooleanOption.js.map +0 -1
  81. package/IsSanctionedSimpleUnitIdentifier.js.map +0 -1
  82. package/IsValidTimeZoneName.js.map +0 -1
  83. package/IsWellFormedCurrencyCode.js.map +0 -1
  84. package/IsWellFormedUnitIdentifier.js.map +0 -1
  85. package/NumberFormat/ApplyUnsignedRoundingMode.js.map +0 -1
  86. package/NumberFormat/CollapseNumberRange.js.map +0 -1
  87. package/NumberFormat/ComputeExponent.js.map +0 -1
  88. package/NumberFormat/ComputeExponentForMagnitude.js.map +0 -1
  89. package/NumberFormat/CurrencyDigits.js.map +0 -1
  90. package/NumberFormat/FormatApproximately.js.map +0 -1
  91. package/NumberFormat/FormatNumericRange.js.map +0 -1
  92. package/NumberFormat/FormatNumericRangeToParts.js.map +0 -1
  93. package/NumberFormat/FormatNumericToParts.js.map +0 -1
  94. package/NumberFormat/FormatNumericToString.js.map +0 -1
  95. package/NumberFormat/GetUnsignedRoundingMode.js.map +0 -1
  96. package/NumberFormat/InitializeNumberFormat.js.map +0 -1
  97. package/NumberFormat/PartitionNumberPattern.js.map +0 -1
  98. package/NumberFormat/PartitionNumberRangePattern.js.map +0 -1
  99. package/NumberFormat/SetNumberFormatDigitOptions.js.map +0 -1
  100. package/NumberFormat/SetNumberFormatUnitOptions.js.map +0 -1
  101. package/NumberFormat/ToRawFixed.js.map +0 -1
  102. package/NumberFormat/ToRawPrecision.js.map +0 -1
  103. package/NumberFormat/digit-mapping.generated.js.map +0 -1
  104. package/NumberFormat/format_to_parts.js.map +0 -1
  105. package/PartitionPattern.js.map +0 -1
  106. package/SupportedLocales.js.map +0 -1
  107. package/data.js.map +0 -1
  108. package/index.js.map +0 -1
  109. package/lib/262.js.map +0 -1
  110. package/lib/CanonicalizeLocaleList.js.map +0 -1
  111. package/lib/CanonicalizeTimeZoneName.js.map +0 -1
  112. package/lib/CoerceOptionsToObject.js.map +0 -1
  113. package/lib/DefaultNumberOption.js.map +0 -1
  114. package/lib/GetNumberOption.js.map +0 -1
  115. package/lib/GetOption.js.map +0 -1
  116. package/lib/GetOptionsObject.js.map +0 -1
  117. package/lib/GetStringOrBooleanOption.js.map +0 -1
  118. package/lib/IsSanctionedSimpleUnitIdentifier.js.map +0 -1
  119. package/lib/IsValidTimeZoneName.js.map +0 -1
  120. package/lib/IsWellFormedCurrencyCode.js.map +0 -1
  121. package/lib/IsWellFormedUnitIdentifier.js.map +0 -1
  122. package/lib/NumberFormat/ApplyUnsignedRoundingMode.js.map +0 -1
  123. package/lib/NumberFormat/CollapseNumberRange.js.map +0 -1
  124. package/lib/NumberFormat/ComputeExponent.js.map +0 -1
  125. package/lib/NumberFormat/ComputeExponentForMagnitude.js.map +0 -1
  126. package/lib/NumberFormat/CurrencyDigits.js.map +0 -1
  127. package/lib/NumberFormat/FormatApproximately.js.map +0 -1
  128. package/lib/NumberFormat/FormatNumericRange.js.map +0 -1
  129. package/lib/NumberFormat/FormatNumericRangeToParts.js.map +0 -1
  130. package/lib/NumberFormat/FormatNumericToParts.js.map +0 -1
  131. package/lib/NumberFormat/FormatNumericToString.js.map +0 -1
  132. package/lib/NumberFormat/GetUnsignedRoundingMode.js.map +0 -1
  133. package/lib/NumberFormat/InitializeNumberFormat.js.map +0 -1
  134. package/lib/NumberFormat/PartitionNumberPattern.js.map +0 -1
  135. package/lib/NumberFormat/PartitionNumberRangePattern.js.map +0 -1
  136. package/lib/NumberFormat/SetNumberFormatDigitOptions.js.map +0 -1
  137. package/lib/NumberFormat/SetNumberFormatUnitOptions.js.map +0 -1
  138. package/lib/NumberFormat/ToRawFixed.js.map +0 -1
  139. package/lib/NumberFormat/ToRawPrecision.js.map +0 -1
  140. package/lib/NumberFormat/digit-mapping.generated.js.map +0 -1
  141. package/lib/NumberFormat/format_to_parts.js.map +0 -1
  142. package/lib/PartitionPattern.js.map +0 -1
  143. package/lib/SupportedLocales.js.map +0 -1
  144. package/lib/data.js.map +0 -1
  145. package/lib/index.js.map +0 -1
  146. package/lib/regex.generated.js.map +0 -1
  147. package/lib/types/core.js.map +0 -1
  148. package/lib/types/date-time.js.map +0 -1
  149. package/lib/types/displaynames.js.map +0 -1
  150. package/lib/types/list.js.map +0 -1
  151. package/lib/types/number.js.map +0 -1
  152. package/lib/types/plural-rules.js.map +0 -1
  153. package/lib/types/relative-time.js.map +0 -1
  154. package/lib/utils.js.map +0 -1
  155. package/regex.generated.js.map +0 -1
  156. package/types/core.js.map +0 -1
  157. package/types/date-time.js.map +0 -1
  158. package/types/displaynames.js.map +0 -1
  159. package/types/list.js.map +0 -1
  160. package/types/number.js.map +0 -1
  161. package/types/plural-rules.js.map +0 -1
  162. package/types/relative-time.js.map +0 -1
  163. package/utils.js.map +0 -1
@@ -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;
@@ -1,47 +1,77 @@
1
- import { repeat, getMagnitude } from '../utils';
2
- export function ToRawPrecision(x, minPrecision, maxPrecision) {
1
+ import Decimal from 'decimal.js';
2
+ import { TEN, ZERO } from '../constants';
3
+ import { invariant, repeat } from '../utils';
4
+ import { ApplyUnsignedRoundingMode } from './ApplyUnsignedRoundingMode';
5
+ Decimal.set({
6
+ toExpPos: 100,
7
+ });
8
+ function ToRawPrecisionFn(n, e, p) {
9
+ invariant(TEN.pow(p - 1).lessThanOrEqualTo(n) && n.lessThan(TEN.pow(p)), "n should be in the range ".concat(TEN.pow(p - 1), " <= n < ").concat(TEN.pow(p), " but got ").concat(n));
10
+ // n * 10^(e - p + 1)
11
+ return n.times(TEN.pow(e.minus(p).plus(1)));
12
+ }
13
+ function findN1E1R1(x, p) {
14
+ var maxN1 = TEN.pow(p);
15
+ var minN1 = TEN.pow(p - 1);
16
+ var maxE1 = x.div(minN1).log(10).plus(p).minus(1).ceil();
17
+ for (var currentE1 = maxE1;; currentE1 = currentE1.minus(1)) {
18
+ var currentN1 = x.div(TEN.pow(currentE1.minus(p).plus(1))).floor();
19
+ if (currentN1.lessThan(maxN1) && currentN1.greaterThanOrEqualTo(minN1)) {
20
+ var currentR1 = ToRawPrecisionFn(currentN1, currentE1, p);
21
+ if (currentR1.lessThanOrEqualTo(x)) {
22
+ return {
23
+ n1: currentN1,
24
+ e1: currentE1,
25
+ r1: currentR1,
26
+ };
27
+ }
28
+ }
29
+ }
30
+ }
31
+ function findN2E2R2(x, p) {
32
+ var maxN2 = TEN.pow(p);
33
+ var minN2 = TEN.pow(p - 1);
34
+ var minE2 = x.div(maxN2).log(10).plus(p).minus(1).floor();
35
+ for (var currentE2 = minE2;; currentE2 = currentE2.plus(1)) {
36
+ var currentN2 = x.div(TEN.pow(currentE2.minus(p).plus(1))).ceil();
37
+ if (currentN2.lessThan(maxN2) && currentN2.greaterThanOrEqualTo(minN2)) {
38
+ var currentR2 = ToRawPrecisionFn(currentN2, currentE2, p);
39
+ if (currentR2.greaterThanOrEqualTo(x)) {
40
+ return {
41
+ n2: currentN2,
42
+ e2: currentE2,
43
+ r2: currentR2,
44
+ };
45
+ }
46
+ }
47
+ }
48
+ }
49
+ export function ToRawPrecision(x, minPrecision, maxPrecision, unsignedRoundingMode) {
3
50
  var p = maxPrecision;
4
51
  var m;
5
52
  var e;
6
53
  var xFinal;
7
- if (x === 0) {
54
+ if (x.isZero()) {
8
55
  m = repeat('0', p);
9
56
  e = 0;
10
- xFinal = 0;
57
+ xFinal = ZERO;
11
58
  }
12
59
  else {
13
- var xToString = x.toString();
14
- // If xToString is formatted as scientific notation, the number is either very small or very
15
- // large. If the precision of the formatted string is lower that requested max precision, we
16
- // should still infer them from the formatted string, otherwise the formatted result might have
17
- // precision loss (e.g. 1e41 will not have 0 in every trailing digits).
18
- var xToStringExponentIndex = xToString.indexOf('e');
19
- var _a = xToString.split('e'), xToStringMantissa = _a[0], xToStringExponent = _a[1];
20
- var xToStringMantissaWithoutDecimalPoint = xToStringMantissa.replace('.', '');
21
- if (xToStringExponentIndex >= 0 &&
22
- xToStringMantissaWithoutDecimalPoint.length <= p) {
23
- e = +xToStringExponent;
24
- m =
25
- xToStringMantissaWithoutDecimalPoint +
26
- repeat('0', p - xToStringMantissaWithoutDecimalPoint.length);
27
- xFinal = x;
60
+ var _a = findN1E1R1(x, p), n1 = _a.n1, e1 = _a.e1, r1 = _a.r1;
61
+ var _b = findN2E2R2(x, p), n2 = _b.n2, e2 = _b.e2, r2 = _b.r2;
62
+ var r = ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode);
63
+ var n = void 0;
64
+ if (r.eq(r1)) {
65
+ n = n1;
66
+ e = e1.toNumber();
67
+ xFinal = r1;
28
68
  }
29
69
  else {
30
- e = getMagnitude(x);
31
- var decimalPlaceOffset = e - p + 1;
32
- // n is the integer containing the required precision digits. To derive the formatted string,
33
- // we will adjust its decimal place in the logic below.
34
- var n = Math.round(adjustDecimalPlace(x, decimalPlaceOffset));
35
- // The rounding caused the change of magnitude, so we should increment `e` by 1.
36
- if (adjustDecimalPlace(n, p - 1) >= 10) {
37
- e = e + 1;
38
- // Divide n by 10 to swallow one precision.
39
- n = Math.floor(n / 10);
40
- }
41
- m = n.toString();
42
- // Equivalent of n * 10 ** (e - p + 1)
43
- xFinal = adjustDecimalPlace(n, p - 1 - e);
70
+ n = n2;
71
+ e = e2.toNumber();
72
+ xFinal = r2;
44
73
  }
74
+ m = n.toString();
45
75
  }
46
76
  var int;
47
77
  if (e >= p - 1) {
@@ -49,26 +79,28 @@ export function ToRawPrecision(x, minPrecision, maxPrecision) {
49
79
  int = e + 1;
50
80
  }
51
81
  else if (e >= 0) {
52
- m = "".concat(m.slice(0, e + 1), ".").concat(m.slice(e + 1));
82
+ m = m.slice(0, e + 1) + '.' + m.slice(m.length - (p - (e + 1)));
53
83
  int = e + 1;
54
84
  }
55
85
  else {
56
- m = "0.".concat(repeat('0', -e - 1)).concat(m);
86
+ invariant(e < 0, 'e should be less than 0');
87
+ m = '0.' + repeat('0', -e - 1) + m;
57
88
  int = 1;
58
89
  }
59
- if (m.indexOf('.') >= 0 && maxPrecision > minPrecision) {
90
+ if (m.includes('.') && maxPrecision > minPrecision) {
60
91
  var cut = maxPrecision - minPrecision;
61
92
  while (cut > 0 && m[m.length - 1] === '0') {
62
- m = m.slice(0, -1);
93
+ m = m.slice(0, m.length - 1);
63
94
  cut--;
64
95
  }
65
96
  if (m[m.length - 1] === '.') {
66
- m = m.slice(0, -1);
97
+ m = m.slice(0, m.length - 1);
67
98
  }
68
99
  }
69
- return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int };
70
- // x / (10 ** magnitude), but try to preserve as much floating point precision as possible.
71
- function adjustDecimalPlace(x, magnitude) {
72
- return magnitude < 0 ? x * Math.pow(10, -magnitude) : x / Math.pow(10, magnitude);
73
- }
100
+ return {
101
+ formattedString: m,
102
+ roundedNumber: xFinal,
103
+ integerDigitsCount: int,
104
+ roundingMagnitude: e,
105
+ };
74
106
  }
@@ -1,7 +1,8 @@
1
- import { NumberFormatLocaleInternalData, NumberFormatOptionsCompactDisplay, NumberFormatOptionsCurrencyDisplay, NumberFormatOptionsCurrencySign, NumberFormatOptionsNotation, NumberFormatOptionsStyle, NumberFormatOptionsUnitDisplay, NumberFormatPart, UseGroupingType } from '../types/number';
1
+ import Decimal from 'decimal.js';
2
+ import { NumberFormatLocaleInternalData, NumberFormatOptionsCompactDisplay, NumberFormatOptionsCurrencyDisplay, NumberFormatOptionsCurrencySign, NumberFormatOptionsNotation, NumberFormatOptionsStyle, NumberFormatOptionsUnitDisplay, NumberFormatPart, RoundingModeType, UseGroupingType } from '../types/number';
2
3
  interface NumberResult {
3
4
  formattedString: string;
4
- roundedNumber: number;
5
+ roundedNumber: Decimal;
5
6
  sign: -1 | 0 | 1;
6
7
  exponent: number;
7
8
  magnitude: number;
@@ -17,5 +18,7 @@ export default function formatToParts(numberResult: NumberResult, data: NumberFo
17
18
  currencySign?: NumberFormatOptionsCurrencySign;
18
19
  unit?: string;
19
20
  unitDisplay?: NumberFormatOptionsUnitDisplay;
21
+ roundingIncrement: number;
22
+ roundingMode: RoundingModeType;
20
23
  }): NumberFormatPart[];
21
24
  export {};