@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
@@ -2,10 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PartitionNumberPattern = PartitionNumberPattern;
4
4
  var tslib_1 = require("tslib");
5
- var FormatNumericToString_1 = require("./FormatNumericToString");
6
- var _262_1 = require("../262");
5
+ var constants_1 = require("../constants");
6
+ var utils_1 = require("../utils");
7
7
  var ComputeExponent_1 = require("./ComputeExponent");
8
8
  var format_to_parts_1 = tslib_1.__importDefault(require("./format_to_parts"));
9
+ var FormatNumericToString_1 = require("./FormatNumericToString");
9
10
  /**
10
11
  * https://tc39.es/ecma402/#sec-formatnumberstring
11
12
  */
@@ -19,26 +20,23 @@ function PartitionNumberPattern(numberFormat, x, _a) {
19
20
  var magnitude = 0;
20
21
  var exponent = 0;
21
22
  var n;
22
- if (isNaN(x)) {
23
+ if (x.isNaN()) {
23
24
  n = symbols.nan;
24
25
  }
25
- else if (x == Number.POSITIVE_INFINITY || x == Number.NEGATIVE_INFINITY) {
26
+ else if (!x.isFinite()) {
26
27
  n = symbols.infinity;
27
28
  }
28
29
  else {
29
- if (!(0, _262_1.SameValue)(x, -0)) {
30
- if (!isFinite(x)) {
31
- throw new Error('Input must be a mathematical value');
32
- }
30
+ if (!x.isZero()) {
31
+ (0, utils_1.invariant)(x.isFinite(), 'Input must be a mathematical value');
33
32
  if (internalSlots.style == 'percent') {
34
- x *= 100;
33
+ x = x.times(100);
35
34
  }
36
35
  ;
37
36
  _b = (0, ComputeExponent_1.ComputeExponent)(numberFormat, x, {
38
37
  getInternalSlots: getInternalSlots,
39
38
  }), exponent = _b[0], magnitude = _b[1];
40
- // Preserve more precision by doing multiplication when exponent is negative.
41
- x = exponent < 0 ? x * Math.pow(10, -exponent) : x / Math.pow(10, exponent);
39
+ x = x.times(constants_1.TEN.pow(-exponent));
42
40
  }
43
41
  var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(internalSlots, x);
44
42
  n = formatNumberResult.formattedString;
@@ -53,7 +51,7 @@ function PartitionNumberPattern(numberFormat, x, _a) {
53
51
  sign = 0;
54
52
  break;
55
53
  case 'auto':
56
- if ((0, _262_1.SameValue)(x, 0) || x > 0 || isNaN(x)) {
54
+ if (x.isPositive() || x.isNaN()) {
57
55
  sign = 0;
58
56
  }
59
57
  else {
@@ -61,24 +59,33 @@ function PartitionNumberPattern(numberFormat, x, _a) {
61
59
  }
62
60
  break;
63
61
  case 'always':
64
- if ((0, _262_1.SameValue)(x, 0) || x > 0 || isNaN(x)) {
62
+ if (x.isPositive() || x.isNaN()) {
65
63
  sign = 1;
66
64
  }
67
65
  else {
68
66
  sign = -1;
69
67
  }
70
68
  break;
71
- default:
72
- // x === 0 -> x is 0 or x is -0
73
- if (x === 0 || isNaN(x)) {
69
+ case 'exceptZero':
70
+ if (x.isZero()) {
74
71
  sign = 0;
75
72
  }
76
- else if (x > 0) {
77
- sign = 1;
73
+ else if (x.isNegative()) {
74
+ sign = -1;
78
75
  }
79
76
  else {
77
+ sign = 1;
78
+ }
79
+ break;
80
+ default:
81
+ (0, utils_1.invariant)(signDisplay === 'negative', 'signDisplay must be "negative"');
82
+ if (x.isNegative() && !x.isZero()) {
80
83
  sign = -1;
81
84
  }
85
+ else {
86
+ sign = 0;
87
+ }
88
+ break;
82
89
  }
83
90
  return (0, format_to_parts_1.default)({ roundedNumber: x, formattedString: n, exponent: exponent, magnitude: magnitude, sign: sign }, internalSlots.dataLocaleData, pl, internalSlots);
84
91
  }
@@ -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,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PartitionNumberRangePattern = PartitionNumberRangePattern;
4
+ var utils_1 = require("../utils");
4
5
  var CollapseNumberRange_1 = require("./CollapseNumberRange");
5
6
  var FormatApproximately_1 = require("./FormatApproximately");
6
7
  var PartitionNumberPattern_1 = require("./PartitionNumberPattern");
@@ -9,9 +10,7 @@ var PartitionNumberPattern_1 = require("./PartitionNumberPattern");
9
10
  */
10
11
  function PartitionNumberRangePattern(numberFormat, x, y, _a) {
11
12
  var getInternalSlots = _a.getInternalSlots;
12
- if (isNaN(x) || isNaN(y)) {
13
- throw new RangeError('Input must be a number');
14
- }
13
+ (0, utils_1.invariant)(!x.isNaN() && !y.isNaN(), 'Input must be a number');
15
14
  var result = [];
16
15
  var xResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(numberFormat, x, { getInternalSlots: getInternalSlots });
17
16
  var yResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(numberFormat, y, { getInternalSlots: getInternalSlots });
@@ -4,6 +4,10 @@ exports.SetNumberFormatDigitOptions = SetNumberFormatDigitOptions;
4
4
  var DefaultNumberOption_1 = require("../DefaultNumberOption");
5
5
  var GetNumberOption_1 = require("../GetNumberOption");
6
6
  var GetOption_1 = require("../GetOption");
7
+ var utils_1 = require("../utils");
8
+ var VALID_ROUNDING_INCREMENTS = new Set([
9
+ 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000,
10
+ ]);
7
11
  /**
8
12
  * https://tc39.es/ecma402/#sec-setnfdigitoptions
9
13
  */
@@ -14,7 +18,27 @@ function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mxfdDefau
14
18
  var mnsd = opts.minimumSignificantDigits;
15
19
  var mxsd = opts.maximumSignificantDigits;
16
20
  internalSlots.minimumIntegerDigits = mnid;
21
+ var roundingIncrement = (0, GetNumberOption_1.GetNumberOption)(opts, 'roundingIncrement', 1, 5000, 1);
22
+ (0, utils_1.invariant)(VALID_ROUNDING_INCREMENTS.has(roundingIncrement), "Invalid rounding increment value: ".concat(roundingIncrement, ".\nValid values are ").concat(Array.from(VALID_ROUNDING_INCREMENTS).join(', '), "."));
23
+ var roundingMode = (0, GetOption_1.GetOption)(opts, 'roundingMode', 'string', [
24
+ 'ceil',
25
+ 'floor',
26
+ 'expand',
27
+ 'trunc',
28
+ 'halfCeil',
29
+ 'halfFloor',
30
+ 'halfExpand',
31
+ 'halfTrunc',
32
+ 'halfEven',
33
+ ], 'halfExpand');
17
34
  var roundingPriority = (0, GetOption_1.GetOption)(opts, 'roundingPriority', 'string', ['auto', 'morePrecision', 'lessPrecision'], 'auto');
35
+ var trailingZeroDisplay = (0, GetOption_1.GetOption)(opts, 'trailingZeroDisplay', 'string', ['auto', 'stripIfInteger'], 'auto');
36
+ if (roundingIncrement !== 1) {
37
+ mxfdDefault = mnfdDefault;
38
+ }
39
+ internalSlots.roundingIncrement = roundingIncrement;
40
+ internalSlots.roundingMode = roundingMode;
41
+ internalSlots.trailingZeroDisplay = trailingZeroDisplay;
18
42
  var hasSd = mnsd !== undefined || mxsd !== undefined;
19
43
  var hasFd = mnfd !== undefined || mxfd !== undefined;
20
44
  var needSd = true;
@@ -27,10 +51,8 @@ function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mxfdDefau
27
51
  }
28
52
  if (needSd) {
29
53
  if (hasSd) {
30
- mnsd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnsd, 1, 21, 1);
31
- mxsd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxsd, mnsd, 21, 21);
32
- internalSlots.minimumSignificantDigits = mnsd;
33
- internalSlots.maximumSignificantDigits = mxsd;
54
+ internalSlots.minimumSignificantDigits = (0, DefaultNumberOption_1.DefaultNumberOption)(mnsd, 1, 21, 1);
55
+ internalSlots.maximumSignificantDigits = (0, DefaultNumberOption_1.DefaultNumberOption)(mxsd, internalSlots.minimumSignificantDigits, 21, 21);
34
56
  }
35
57
  else {
36
58
  internalSlots.minimumSignificantDigits = 1;
@@ -39,11 +61,10 @@ function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mxfdDefau
39
61
  }
40
62
  if (needFd) {
41
63
  if (hasFd) {
42
- mnfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnfd, 0, 20, undefined);
43
- mxfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxfd, 0, 20, undefined);
64
+ mnfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnfd, 0, 100, undefined);
65
+ mxfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxfd, 0, 100, undefined);
44
66
  if (mnfd === undefined) {
45
- // @ts-expect-error
46
- mnfd = Math.min(mnfdDefault, mxfd);
67
+ mnfd = Math.min(mnfdDefault, mxfd !== null && mxfd !== void 0 ? mxfd : 0);
47
68
  }
48
69
  else if (mxfd === undefined) {
49
70
  mxfd = Math.max(mxfdDefault, mnfd);
@@ -59,25 +80,33 @@ function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mxfdDefau
59
80
  internalSlots.maximumFractionDigits = mxfdDefault;
60
81
  }
61
82
  }
62
- if (needSd || needFd) {
63
- if (roundingPriority === 'morePrecision') {
64
- internalSlots.roundingType = 'morePrecision';
65
- }
66
- else if (roundingPriority === 'lessPrecision') {
67
- internalSlots.roundingType = 'lessPrecision';
68
- }
69
- else if (hasSd) {
70
- internalSlots.roundingType = 'significantDigits';
71
- }
72
- else {
73
- internalSlots.roundingType = 'fractionDigits';
74
- }
75
- }
76
- else {
77
- internalSlots.roundingType = 'morePrecision';
83
+ if (!needSd && !needFd) {
78
84
  internalSlots.minimumFractionDigits = 0;
79
85
  internalSlots.maximumFractionDigits = 0;
80
86
  internalSlots.minimumSignificantDigits = 1;
81
87
  internalSlots.maximumSignificantDigits = 2;
88
+ internalSlots.roundingType = 'morePrecision';
89
+ internalSlots.roundingPriority = 'morePrecision';
90
+ }
91
+ else if (roundingPriority === 'morePrecision') {
92
+ internalSlots.roundingType = 'morePrecision';
93
+ internalSlots.roundingPriority = 'morePrecision';
94
+ }
95
+ else if (roundingPriority === 'lessPrecision') {
96
+ internalSlots.roundingType = 'lessPrecision';
97
+ internalSlots.roundingPriority = 'lessPrecision';
98
+ }
99
+ else if (hasSd) {
100
+ internalSlots.roundingType = 'significantDigits';
101
+ internalSlots.roundingPriority = 'auto';
102
+ }
103
+ else {
104
+ internalSlots.roundingType = 'fractionDigits';
105
+ internalSlots.roundingPriority = 'auto';
106
+ }
107
+ if (roundingIncrement !== 1) {
108
+ (0, utils_1.invariant)(internalSlots.roundingType === 'fractionDigits', 'Invalid roundingType');
109
+ (0, utils_1.invariant)(internalSlots.maximumFractionDigits ===
110
+ internalSlots.minimumFractionDigits, 'With roundingIncrement > 1, maximumFractionDigits and minimumFractionDigits must be equal.');
82
111
  }
83
112
  }
@@ -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,7 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ToRawFixed = ToRawFixed;
4
+ var tslib_1 = require("tslib");
5
+ var decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
6
+ var constants_1 = require("../constants");
4
7
  var utils_1 = require("../utils");
8
+ var ApplyUnsignedRoundingMode_1 = require("./ApplyUnsignedRoundingMode");
9
+ decimal_js_1.default.set({
10
+ toExpPos: 100,
11
+ });
12
+ function ToRawFixedFn(n, f) {
13
+ return n.times(constants_1.TEN.pow(-f));
14
+ }
15
+ function findN1R1(x, f, roundingIncrement) {
16
+ var nx = x.times(constants_1.TEN.pow(f)).floor();
17
+ var n1 = nx.div(roundingIncrement).floor().times(roundingIncrement);
18
+ var r1 = ToRawFixedFn(n1, f);
19
+ return {
20
+ n1: n1,
21
+ r1: r1,
22
+ };
23
+ }
24
+ function findN2R2(x, f, roundingIncrement) {
25
+ var nx = x.times(constants_1.TEN.pow(f)).ceil();
26
+ var n2 = nx.div(roundingIncrement).ceil().times(roundingIncrement);
27
+ var r2 = ToRawFixedFn(n2, f);
28
+ return {
29
+ n2: n2,
30
+ r2: r2,
31
+ };
32
+ }
5
33
  /**
6
34
  * TODO: dedup with intl-pluralrules and support BigInt
7
35
  * https://tc39.es/ecma402/#sec-torawfixed
@@ -9,34 +37,38 @@ var utils_1 = require("../utils");
9
37
  * @param minFraction and integer between 0 and 20
10
38
  * @param maxFraction and integer between 0 and 20
11
39
  */
12
- function ToRawFixed(x, minFraction, maxFraction) {
40
+ function ToRawFixed(x, minFraction, maxFraction, roundingIncrement, unsignedRoundingMode) {
13
41
  var f = maxFraction;
14
- var n = Math.round(x * Math.pow(10, f));
15
- var xFinal = n / Math.pow(10, f);
16
- // n is a positive integer, but it is possible to be greater than 1e21.
17
- // In such case we will go the slow path.
18
- // See also: https://tc39.es/ecma262/#sec-numeric-types-number-tostring
42
+ var _a = findN1R1(x, f, roundingIncrement), n1 = _a.n1, r1 = _a.r1;
43
+ var _b = findN2R2(x, f, roundingIncrement), n2 = _b.n2, r2 = _b.r2;
44
+ var r = (0, ApplyUnsignedRoundingMode_1.ApplyUnsignedRoundingMode)(x, r1, r2, unsignedRoundingMode);
45
+ var n, xFinal;
19
46
  var m;
20
- if (n < 1e21) {
21
- m = n.toString();
47
+ if (r.eq(r1)) {
48
+ n = n1;
49
+ xFinal = r1;
50
+ }
51
+ else {
52
+ n = n2;
53
+ xFinal = r2;
54
+ }
55
+ if (n.isZero()) {
56
+ m = '0';
22
57
  }
23
58
  else {
24
59
  m = n.toString();
25
- var _a = m.split('e'), mantissa = _a[0], exponent = _a[1];
26
- m = mantissa.replace('.', '');
27
- m = m + (0, utils_1.repeat)('0', Math.max(+exponent - m.length + 1, 0));
28
60
  }
29
61
  var int;
30
62
  if (f !== 0) {
31
63
  var k = m.length;
32
64
  if (k <= f) {
33
- var z = (0, utils_1.repeat)('0', f + 1 - k);
65
+ var z = (0, utils_1.repeat)('0', f - k + 1);
34
66
  m = z + m;
35
67
  k = f + 1;
36
68
  }
37
69
  var a = m.slice(0, k - f);
38
- var b = m.slice(k - f);
39
- m = "".concat(a, ".").concat(b);
70
+ var b = m.slice(m.length - f);
71
+ m = a + '.' + b;
40
72
  int = a.length;
41
73
  }
42
74
  else {
@@ -44,11 +76,16 @@ function ToRawFixed(x, minFraction, maxFraction) {
44
76
  }
45
77
  var cut = maxFraction - minFraction;
46
78
  while (cut > 0 && m[m.length - 1] === '0') {
47
- m = m.slice(0, -1);
79
+ m = m.slice(0, m.length - 1);
48
80
  cut--;
49
81
  }
50
- if (m[m.length - 1] === '.') {
51
- m = m.slice(0, -1);
82
+ if (m[m.length - 1] === '\u002e') {
83
+ m = m.slice(0, m.length - 1);
52
84
  }
53
- return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int };
85
+ return {
86
+ formattedString: m,
87
+ roundedNumber: xFinal,
88
+ integerDigitsCount: int,
89
+ roundingMagnitude: -f,
90
+ };
54
91
  }
@@ -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,50 +1,81 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ToRawPrecision = ToRawPrecision;
4
+ var tslib_1 = require("tslib");
5
+ var decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
6
+ var constants_1 = require("../constants");
4
7
  var utils_1 = require("../utils");
5
- function ToRawPrecision(x, minPrecision, maxPrecision) {
8
+ var ApplyUnsignedRoundingMode_1 = require("./ApplyUnsignedRoundingMode");
9
+ decimal_js_1.default.set({
10
+ toExpPos: 100,
11
+ });
12
+ function ToRawPrecisionFn(n, e, p) {
13
+ (0, utils_1.invariant)(constants_1.TEN.pow(p - 1).lessThanOrEqualTo(n) && n.lessThan(constants_1.TEN.pow(p)), "n should be in the range ".concat(constants_1.TEN.pow(p - 1), " <= n < ").concat(constants_1.TEN.pow(p), " but got ").concat(n));
14
+ // n * 10^(e - p + 1)
15
+ return n.times(constants_1.TEN.pow(e.minus(p).plus(1)));
16
+ }
17
+ function findN1E1R1(x, p) {
18
+ var maxN1 = constants_1.TEN.pow(p);
19
+ var minN1 = constants_1.TEN.pow(p - 1);
20
+ var maxE1 = x.div(minN1).log(10).plus(p).minus(1).ceil();
21
+ for (var currentE1 = maxE1;; currentE1 = currentE1.minus(1)) {
22
+ var currentN1 = x.div(constants_1.TEN.pow(currentE1.minus(p).plus(1))).floor();
23
+ if (currentN1.lessThan(maxN1) && currentN1.greaterThanOrEqualTo(minN1)) {
24
+ var currentR1 = ToRawPrecisionFn(currentN1, currentE1, p);
25
+ if (currentR1.lessThanOrEqualTo(x)) {
26
+ return {
27
+ n1: currentN1,
28
+ e1: currentE1,
29
+ r1: currentR1,
30
+ };
31
+ }
32
+ }
33
+ }
34
+ }
35
+ function findN2E2R2(x, p) {
36
+ var maxN2 = constants_1.TEN.pow(p);
37
+ var minN2 = constants_1.TEN.pow(p - 1);
38
+ var minE2 = x.div(maxN2).log(10).plus(p).minus(1).floor();
39
+ for (var currentE2 = minE2;; currentE2 = currentE2.plus(1)) {
40
+ var currentN2 = x.div(constants_1.TEN.pow(currentE2.minus(p).plus(1))).ceil();
41
+ if (currentN2.lessThan(maxN2) && currentN2.greaterThanOrEqualTo(minN2)) {
42
+ var currentR2 = ToRawPrecisionFn(currentN2, currentE2, p);
43
+ if (currentR2.greaterThanOrEqualTo(x)) {
44
+ return {
45
+ n2: currentN2,
46
+ e2: currentE2,
47
+ r2: currentR2,
48
+ };
49
+ }
50
+ }
51
+ }
52
+ }
53
+ function ToRawPrecision(x, minPrecision, maxPrecision, unsignedRoundingMode) {
6
54
  var p = maxPrecision;
7
55
  var m;
8
56
  var e;
9
57
  var xFinal;
10
- if (x === 0) {
58
+ if (x.isZero()) {
11
59
  m = (0, utils_1.repeat)('0', p);
12
60
  e = 0;
13
- xFinal = 0;
61
+ xFinal = constants_1.ZERO;
14
62
  }
15
63
  else {
16
- var xToString = x.toString();
17
- // If xToString is formatted as scientific notation, the number is either very small or very
18
- // large. If the precision of the formatted string is lower that requested max precision, we
19
- // should still infer them from the formatted string, otherwise the formatted result might have
20
- // precision loss (e.g. 1e41 will not have 0 in every trailing digits).
21
- var xToStringExponentIndex = xToString.indexOf('e');
22
- var _a = xToString.split('e'), xToStringMantissa = _a[0], xToStringExponent = _a[1];
23
- var xToStringMantissaWithoutDecimalPoint = xToStringMantissa.replace('.', '');
24
- if (xToStringExponentIndex >= 0 &&
25
- xToStringMantissaWithoutDecimalPoint.length <= p) {
26
- e = +xToStringExponent;
27
- m =
28
- xToStringMantissaWithoutDecimalPoint +
29
- (0, utils_1.repeat)('0', p - xToStringMantissaWithoutDecimalPoint.length);
30
- xFinal = x;
64
+ var _a = findN1E1R1(x, p), n1 = _a.n1, e1 = _a.e1, r1 = _a.r1;
65
+ var _b = findN2E2R2(x, p), n2 = _b.n2, e2 = _b.e2, r2 = _b.r2;
66
+ var r = (0, ApplyUnsignedRoundingMode_1.ApplyUnsignedRoundingMode)(x, r1, r2, unsignedRoundingMode);
67
+ var n = void 0;
68
+ if (r.eq(r1)) {
69
+ n = n1;
70
+ e = e1.toNumber();
71
+ xFinal = r1;
31
72
  }
32
73
  else {
33
- e = (0, utils_1.getMagnitude)(x);
34
- var decimalPlaceOffset = e - p + 1;
35
- // n is the integer containing the required precision digits. To derive the formatted string,
36
- // we will adjust its decimal place in the logic below.
37
- var n = Math.round(adjustDecimalPlace(x, decimalPlaceOffset));
38
- // The rounding caused the change of magnitude, so we should increment `e` by 1.
39
- if (adjustDecimalPlace(n, p - 1) >= 10) {
40
- e = e + 1;
41
- // Divide n by 10 to swallow one precision.
42
- n = Math.floor(n / 10);
43
- }
44
- m = n.toString();
45
- // Equivalent of n * 10 ** (e - p + 1)
46
- xFinal = adjustDecimalPlace(n, p - 1 - e);
74
+ n = n2;
75
+ e = e2.toNumber();
76
+ xFinal = r2;
47
77
  }
78
+ m = n.toString();
48
79
  }
49
80
  var int;
50
81
  if (e >= p - 1) {
@@ -52,26 +83,28 @@ function ToRawPrecision(x, minPrecision, maxPrecision) {
52
83
  int = e + 1;
53
84
  }
54
85
  else if (e >= 0) {
55
- m = "".concat(m.slice(0, e + 1), ".").concat(m.slice(e + 1));
86
+ m = m.slice(0, e + 1) + '.' + m.slice(m.length - (p - (e + 1)));
56
87
  int = e + 1;
57
88
  }
58
89
  else {
59
- m = "0.".concat((0, utils_1.repeat)('0', -e - 1)).concat(m);
90
+ (0, utils_1.invariant)(e < 0, 'e should be less than 0');
91
+ m = '0.' + (0, utils_1.repeat)('0', -e - 1) + m;
60
92
  int = 1;
61
93
  }
62
- if (m.indexOf('.') >= 0 && maxPrecision > minPrecision) {
94
+ if (m.includes('.') && maxPrecision > minPrecision) {
63
95
  var cut = maxPrecision - minPrecision;
64
96
  while (cut > 0 && m[m.length - 1] === '0') {
65
- m = m.slice(0, -1);
97
+ m = m.slice(0, m.length - 1);
66
98
  cut--;
67
99
  }
68
100
  if (m[m.length - 1] === '.') {
69
- m = m.slice(0, -1);
101
+ m = m.slice(0, m.length - 1);
70
102
  }
71
103
  }
72
- return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int };
73
- // x / (10 ** magnitude), but try to preserve as much floating point precision as possible.
74
- function adjustDecimalPlace(x, magnitude) {
75
- return magnitude < 0 ? x * Math.pow(10, -magnitude) : x / Math.pow(10, magnitude);
76
- }
104
+ return {
105
+ formattedString: m,
106
+ roundedNumber: xFinal,
107
+ integerDigitsCount: int,
108
+ roundingMagnitude: e,
109
+ };
77
110
  }
@@ -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 {};