@utiliread/primitives 1.0.0-146 → 1.0.0-147
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.
- package/package.json +1 -1
- package/src/number-formatter.spec.ts +21 -0
- package/src/number-formatter.ts +17 -9
- package/src/precision-number.spec.ts +134 -3
- package/src/precision-number.ts +123 -17
package/package.json
CHANGED
|
@@ -547,3 +547,24 @@ describe("toLocaleFixed", () => {
|
|
|
547
547
|
);
|
|
548
548
|
});
|
|
549
549
|
});
|
|
550
|
+
|
|
551
|
+
describe("zero", () => {
|
|
552
|
+
it("should format zero with precision as number of decimals", () => {
|
|
553
|
+
expect(NumberFormatter.toPrecision(0, 0)).to.equal("0");
|
|
554
|
+
expect(NumberFormatter.toPrecision(0, 1)).to.equal("0.0");
|
|
555
|
+
expect(NumberFormatter.toPrecision(0, 2)).to.equal("0.00");
|
|
556
|
+
expect(NumberFormatter.toFixed(0, 0)).to.equal("0");
|
|
557
|
+
expect(NumberFormatter.toFixed(0, 2)).to.equal("0.00");
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
it("should limit the decimals of zero to maxDecimals", () => {
|
|
561
|
+
expect(NumberFormatter.toFixed(0, 3, 2)).to.equal("0.00");
|
|
562
|
+
expect(NumberFormatter.toFixed(0, 3, 0)).to.equal("0");
|
|
563
|
+
expect(NumberFormatter.toFixed(0, 1, 2)).to.equal("0.0");
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it("should not throw for a non-zero value with precision 0", () => {
|
|
567
|
+
expect(NumberFormatter.toFixed(5, 0)).to.equal("5");
|
|
568
|
+
expect(NumberFormatter.toFixed(0.4, 0)).to.equal("0.4");
|
|
569
|
+
});
|
|
570
|
+
});
|
package/src/number-formatter.ts
CHANGED
|
@@ -10,15 +10,8 @@ export interface Parts {
|
|
|
10
10
|
|
|
11
11
|
class Formatter {
|
|
12
12
|
public toPrecision(value: number, precision: number, maxDecimals?: number) {
|
|
13
|
-
const absValue = Math.abs(value);
|
|
14
|
-
const noOfIntegerDigits = Math.round(absValue).toString().length;
|
|
15
|
-
|
|
16
|
-
// Adjust precision to maxDecimals
|
|
17
|
-
if (maxDecimals !== undefined) {
|
|
18
|
-
precision = Math.min(precision, noOfIntegerDigits + maxDecimals);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
13
|
if (value === 0) {
|
|
14
|
+
// By convention the precision of zero is its number of decimals.
|
|
22
15
|
// (0).toPrecision(1) == "0"
|
|
23
16
|
// (0).toPrecision(2) == "0.0"
|
|
24
17
|
// (0).toPrecision(3) == "0.00"
|
|
@@ -26,9 +19,24 @@ class Formatter {
|
|
|
26
19
|
// Formatter.toPrecision(0, 0) == "0"
|
|
27
20
|
// Formatter.toPrecision(0, 1) == "0.0"
|
|
28
21
|
// Formatter.toPrecision(0, 2) == "0.00"
|
|
29
|
-
|
|
22
|
+
const decimals =
|
|
23
|
+
maxDecimals !== undefined
|
|
24
|
+
? Math.min(precision, maxDecimals)
|
|
25
|
+
: precision;
|
|
26
|
+
return (0).toPrecision(Math.max(decimals, 0) + 1);
|
|
30
27
|
}
|
|
31
28
|
|
|
29
|
+
const absValue = Math.abs(value);
|
|
30
|
+
const noOfIntegerDigits = Math.round(absValue).toString().length;
|
|
31
|
+
|
|
32
|
+
// Adjust precision to maxDecimals
|
|
33
|
+
if (maxDecimals !== undefined) {
|
|
34
|
+
precision = Math.min(precision, noOfIntegerDigits + maxDecimals);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// A precision of 0 is only valid for zero, use at least one significant digit for any other value
|
|
38
|
+
precision = Math.max(precision, 1);
|
|
39
|
+
|
|
32
40
|
if (absValue < 1) {
|
|
33
41
|
return value.toPrecision(precision);
|
|
34
42
|
}
|
|
@@ -3,9 +3,12 @@ import { expect } from "chai";
|
|
|
3
3
|
|
|
4
4
|
describe("new", () => {
|
|
5
5
|
it("should create 0", () => {
|
|
6
|
+
// The precision of zero is its number of decimals
|
|
6
7
|
const number = new PrecisionNumber(0);
|
|
7
8
|
expect(number.value).to.equal(0);
|
|
8
|
-
expect(number.precision).to.equal(
|
|
9
|
+
expect(number.precision).to.equal(0);
|
|
10
|
+
expect(number.decimals).to.equal(0);
|
|
11
|
+
expect(number.toFixed()).to.equal("0");
|
|
9
12
|
});
|
|
10
13
|
|
|
11
14
|
it("should create 0.5", () => {
|
|
@@ -17,7 +20,8 @@ describe("new", () => {
|
|
|
17
20
|
it("should create 0.05", () => {
|
|
18
21
|
const number = new PrecisionNumber(0.05);
|
|
19
22
|
expect(number.value).to.equal(0.05);
|
|
20
|
-
expect(number.precision).to.equal(
|
|
23
|
+
expect(number.precision).to.equal(1);
|
|
24
|
+
expect(number.decimals).to.equal(2);
|
|
21
25
|
});
|
|
22
26
|
|
|
23
27
|
it("should create 1.05", () => {
|
|
@@ -43,13 +47,40 @@ describe("parse", () => {
|
|
|
43
47
|
it("should parse '0'", () => {
|
|
44
48
|
const number = PrecisionNumber.parse("0");
|
|
45
49
|
expect(number.value).to.equal(0);
|
|
46
|
-
expect(number.precision).to.equal(
|
|
50
|
+
expect(number.precision).to.equal(0);
|
|
51
|
+
expect(number.toFixed()).to.equal("0");
|
|
47
52
|
});
|
|
48
53
|
|
|
49
54
|
it("should parse '0.0'", () => {
|
|
50
55
|
const number = PrecisionNumber.parse("0.0");
|
|
51
56
|
expect(number.value).to.equal(0);
|
|
52
57
|
expect(number.precision).to.equal(1);
|
|
58
|
+
expect(number.toFixed()).to.equal("0.0");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("should parse '0.00'", () => {
|
|
62
|
+
const number = PrecisionNumber.parse("0.00");
|
|
63
|
+
expect(number.value).to.equal(0);
|
|
64
|
+
expect(number.precision).to.equal(2);
|
|
65
|
+
expect(number.toFixed()).to.equal("0.00");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should parse '0.'", () => {
|
|
69
|
+
const number = PrecisionNumber.parse("0.");
|
|
70
|
+
expect(number.value).to.equal(0);
|
|
71
|
+
expect(number.precision).to.equal(1);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("should parse '-0.0'", () => {
|
|
75
|
+
const number = PrecisionNumber.parse("-0.0");
|
|
76
|
+
expect(number.value).to.equal(0);
|
|
77
|
+
expect(number.precision).to.equal(1);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("should parse '000.00'", () => {
|
|
81
|
+
const number = PrecisionNumber.parse("000.00");
|
|
82
|
+
expect(number.value).to.equal(0);
|
|
83
|
+
expect(number.precision).to.equal(2);
|
|
53
84
|
});
|
|
54
85
|
|
|
55
86
|
it("should parse '1'", () => {
|
|
@@ -175,6 +206,54 @@ describe("plus", () => {
|
|
|
175
206
|
new PrecisionNumber(1024, 3),
|
|
176
207
|
new PrecisionNumber(1024, 3),
|
|
177
208
|
],
|
|
209
|
+
// "0" is the additive identity
|
|
210
|
+
[
|
|
211
|
+
new PrecisionNumber(0, 0),
|
|
212
|
+
new PrecisionNumber(1.25, 3),
|
|
213
|
+
new PrecisionNumber(1.25, 3),
|
|
214
|
+
],
|
|
215
|
+
[
|
|
216
|
+
new PrecisionNumber(1.25, 3),
|
|
217
|
+
new PrecisionNumber(0, 0),
|
|
218
|
+
new PrecisionNumber(1.25, 3),
|
|
219
|
+
],
|
|
220
|
+
[
|
|
221
|
+
new PrecisionNumber(0, 1),
|
|
222
|
+
new PrecisionNumber(1.26, 3),
|
|
223
|
+
new PrecisionNumber(1.26, 2),
|
|
224
|
+
],
|
|
225
|
+
// Zero results have the number of decimals as precision
|
|
226
|
+
[
|
|
227
|
+
new PrecisionNumber(-1, 1),
|
|
228
|
+
new PrecisionNumber(1, 1),
|
|
229
|
+
new PrecisionNumber(0, 0),
|
|
230
|
+
],
|
|
231
|
+
[
|
|
232
|
+
new PrecisionNumber(-1, 2),
|
|
233
|
+
new PrecisionNumber(1, 2),
|
|
234
|
+
new PrecisionNumber(0, 1),
|
|
235
|
+
],
|
|
236
|
+
[
|
|
237
|
+
new PrecisionNumber(-1.25, 3),
|
|
238
|
+
new PrecisionNumber(1.25, 3),
|
|
239
|
+
new PrecisionNumber(0, 2),
|
|
240
|
+
],
|
|
241
|
+
[
|
|
242
|
+
new PrecisionNumber(1.4, 2),
|
|
243
|
+
new PrecisionNumber(-1, 1),
|
|
244
|
+
new PrecisionNumber(0, 0),
|
|
245
|
+
],
|
|
246
|
+
[
|
|
247
|
+
new PrecisionNumber(0, 2),
|
|
248
|
+
new PrecisionNumber(0, 1),
|
|
249
|
+
new PrecisionNumber(0, 1),
|
|
250
|
+
],
|
|
251
|
+
// Sub-1 values
|
|
252
|
+
[
|
|
253
|
+
new PrecisionNumber(0.0625, 3),
|
|
254
|
+
new PrecisionNumber(-0.03125, 1),
|
|
255
|
+
new PrecisionNumber(0.03125, 1),
|
|
256
|
+
],
|
|
178
257
|
];
|
|
179
258
|
|
|
180
259
|
it("should plus correctly", () => {
|
|
@@ -203,6 +282,21 @@ describe("minus", () => {
|
|
|
203
282
|
new PrecisionNumber(0, 1),
|
|
204
283
|
new PrecisionNumber(123, 2),
|
|
205
284
|
],
|
|
285
|
+
[
|
|
286
|
+
new PrecisionNumber(0, 0),
|
|
287
|
+
new PrecisionNumber(123, 2),
|
|
288
|
+
new PrecisionNumber(-123, 2),
|
|
289
|
+
],
|
|
290
|
+
[
|
|
291
|
+
new PrecisionNumber(123, 3),
|
|
292
|
+
new PrecisionNumber(123, 3),
|
|
293
|
+
new PrecisionNumber(0, 0),
|
|
294
|
+
],
|
|
295
|
+
[
|
|
296
|
+
new PrecisionNumber(1.5, 2),
|
|
297
|
+
new PrecisionNumber(1.5, 2),
|
|
298
|
+
new PrecisionNumber(0, 1),
|
|
299
|
+
],
|
|
206
300
|
];
|
|
207
301
|
|
|
208
302
|
it("should minus correctly", () => {
|
|
@@ -214,6 +308,43 @@ describe("minus", () => {
|
|
|
214
308
|
});
|
|
215
309
|
});
|
|
216
310
|
|
|
311
|
+
describe("zero", () => {
|
|
312
|
+
it("should not leave floating point noise", () => {
|
|
313
|
+
const result = new PrecisionNumber(0.3, 1)
|
|
314
|
+
.minus(new PrecisionNumber(0.1, 1))
|
|
315
|
+
.minus(new PrecisionNumber(0.2, 1));
|
|
316
|
+
expect(result.value).to.equal(0);
|
|
317
|
+
expect(result.precision).to.equal(1);
|
|
318
|
+
expect(result.toFixed()).to.equal("0.0");
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
it("should format zero with its number of decimals", () => {
|
|
322
|
+
expect(new PrecisionNumber(0, 0).toFixed()).to.equal("0");
|
|
323
|
+
expect(new PrecisionNumber(0, 1).toFixed()).to.equal("0.0");
|
|
324
|
+
expect(new PrecisionNumber(0, 2).toFixed()).to.equal("0.00");
|
|
325
|
+
expect(new PrecisionNumber(0, 0).toPrecision()).to.equal("0");
|
|
326
|
+
expect(new PrecisionNumber(0, 2).toPrecision()).to.equal("0.00");
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
describe("decimals", () => {
|
|
331
|
+
it("should get the number of decimals", () => {
|
|
332
|
+
expect(new PrecisionNumber(0, 0).decimals).to.equal(0);
|
|
333
|
+
expect(new PrecisionNumber(0, 2).decimals).to.equal(2);
|
|
334
|
+
expect(new PrecisionNumber(0.003, 1).decimals).to.equal(3);
|
|
335
|
+
expect(new PrecisionNumber(0.07, 1).decimals).to.equal(2);
|
|
336
|
+
expect(new PrecisionNumber(0.099, 1).decimals).to.equal(1);
|
|
337
|
+
expect(new PrecisionNumber(0.0999, 2).decimals).to.equal(2);
|
|
338
|
+
expect(new PrecisionNumber(0.1, 3).decimals).to.equal(3);
|
|
339
|
+
expect(new PrecisionNumber(100, 1).decimals).to.equal(-2);
|
|
340
|
+
expect(new PrecisionNumber(100, 4).decimals).to.equal(1);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it("should keep sub-1 values in valueOf", () => {
|
|
344
|
+
expect(PrecisionNumber.parse(".06").valueOf()).to.equal(0.06);
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
|
|
217
348
|
describe("toString", () => {
|
|
218
349
|
it("should return a rounded version in toFixed", () => {
|
|
219
350
|
expect(new PrecisionNumber(2474.581, 6).toFixed()).to.equal("2474.58");
|
package/src/precision-number.ts
CHANGED
|
@@ -4,16 +4,22 @@ import {
|
|
|
4
4
|
localeDecimalSeparator,
|
|
5
5
|
} from "./number-formatter";
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* A number with a number of significant digits (`precision`).
|
|
9
|
+
*
|
|
10
|
+
* Convention for zero (which has no significant digits): the precision is the number of decimals.
|
|
11
|
+
* "0" has precision 0, "0.0" has precision 1, "0.00" has precision 2, etc.
|
|
12
|
+
* A precision of 0 is therefore only valid for the value 0 and must NOT be interpreted as "no precision",
|
|
13
|
+
* i.e. use `precision === undefined` and not `!precision` to test for a missing precision.
|
|
14
|
+
*
|
|
15
|
+
* This is the same convention as `PrecisionDouble` in C#.
|
|
16
|
+
*/
|
|
7
17
|
export class PrecisionNumber {
|
|
8
18
|
public value: number;
|
|
9
19
|
public precision: number;
|
|
10
20
|
|
|
11
21
|
public get decimals() {
|
|
12
|
-
|
|
13
|
-
return this.precision;
|
|
14
|
-
} else {
|
|
15
|
-
return this.precision - getNumberOfIntegralDigits(this.value);
|
|
16
|
-
}
|
|
22
|
+
return getNoOfDecimalPlaces(this.value, this.precision);
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
constructor(value: number, precision?: number) {
|
|
@@ -34,7 +40,8 @@ export class PrecisionNumber {
|
|
|
34
40
|
const value = parseFloat(normalized);
|
|
35
41
|
const precision =
|
|
36
42
|
value === 0
|
|
37
|
-
? 1
|
|
43
|
+
? // The precision of zero is its number of decimals, "0" => 0, "0.0" => 1
|
|
44
|
+
(normalized.split(".", 2)[1]?.length ?? 0)
|
|
38
45
|
: normalized
|
|
39
46
|
.replace(".", "")
|
|
40
47
|
.replace("+", "")
|
|
@@ -48,21 +55,35 @@ export class PrecisionNumber {
|
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
plus(rhs: PrecisionNumber) {
|
|
51
|
-
// The result should have the same number of decimal places as the minimum of the two inputs
|
|
52
58
|
const lhs = this;
|
|
59
|
+
|
|
60
|
+
// "0" (without decimals) is the additive identity
|
|
61
|
+
if (isIntegerZero(lhs)) {
|
|
62
|
+
return rhs;
|
|
63
|
+
} else if (isIntegerZero(rhs)) {
|
|
64
|
+
return lhs;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// The result should have the same number of decimal places as the minimum of the two inputs
|
|
53
68
|
const value = lhs.value + rhs.value;
|
|
54
69
|
const decimals = Math.min(lhs.decimals, rhs.decimals);
|
|
55
|
-
|
|
56
|
-
return new PrecisionNumber(value, precision);
|
|
70
|
+
return fromResult(value, decimals);
|
|
57
71
|
}
|
|
58
72
|
|
|
59
73
|
minus(rhs: PrecisionNumber) {
|
|
60
|
-
// The result should have the same number of decimal places as the minimum of the two inputs
|
|
61
74
|
const lhs = this;
|
|
75
|
+
|
|
76
|
+
// "0" (without decimals) is the additive identity
|
|
77
|
+
if (isIntegerZero(lhs)) {
|
|
78
|
+
return new PrecisionNumber(-rhs.value, rhs.precision);
|
|
79
|
+
} else if (isIntegerZero(rhs)) {
|
|
80
|
+
return lhs;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// The result should have the same number of decimal places as the minimum of the two inputs
|
|
62
84
|
const value = lhs.value - rhs.value;
|
|
63
85
|
const decimals = Math.min(lhs.decimals, rhs.decimals);
|
|
64
|
-
|
|
65
|
-
return new PrecisionNumber(value, precision);
|
|
86
|
+
return fromResult(value, decimals);
|
|
66
87
|
}
|
|
67
88
|
|
|
68
89
|
valueOf() {
|
|
@@ -96,16 +117,101 @@ export class PrecisionNumber {
|
|
|
96
117
|
}
|
|
97
118
|
}
|
|
98
119
|
|
|
120
|
+
function isIntegerZero(number: PrecisionNumber) {
|
|
121
|
+
return number.value === 0 && number.precision === 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Create the result of an addition or subtraction having `decimals` decimal places.
|
|
126
|
+
* A result that is zero at that number of decimal places (e.g. floating point noise from 0.3 - 0.1 - 0.2) becomes an exact zero.
|
|
127
|
+
*/
|
|
128
|
+
function fromResult(value: number, decimals: number) {
|
|
129
|
+
if (decimals >= 0 && Math.abs(value) * Math.pow(10, decimals) < 0.5) {
|
|
130
|
+
return new PrecisionNumber(0, decimals);
|
|
131
|
+
}
|
|
132
|
+
return new PrecisionNumber(value, getPrecision(value, decimals));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Get the precision of `number` having `decimals` decimal places.
|
|
137
|
+
*
|
|
138
|
+
* Number Decimals Precision
|
|
139
|
+
* 0 0 0 ("0")
|
|
140
|
+
* 0 2 2 ("0.00")
|
|
141
|
+
* 0.05 2 1
|
|
142
|
+
* 0.12 2 2
|
|
143
|
+
* 100 1 4
|
|
144
|
+
* 100 0 3
|
|
145
|
+
* 100 -1 2
|
|
146
|
+
* 100 <= -2 1
|
|
147
|
+
*/
|
|
99
148
|
function getPrecision(number: number, decimals?: number) {
|
|
100
149
|
decimals ??= number.toString().split(".", 2)[1]?.length ?? 0;
|
|
101
150
|
|
|
102
|
-
if (number
|
|
103
|
-
|
|
104
|
-
|
|
151
|
+
if (number === 0) {
|
|
152
|
+
// The precision of zero is its number of decimals
|
|
153
|
+
return Math.max(decimals, 0);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const abs = Math.abs(number);
|
|
157
|
+
if (abs < 1) {
|
|
158
|
+
// Leading zeros after the decimal separator are not significant
|
|
159
|
+
return Math.max(decimals - getNoOfLeadingZeros(abs), 1);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return Math.max(getNumberOfIntegralDigits(number) + decimals, 1);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get the number of decimal places of `number` having `precision` significant digits.
|
|
167
|
+
*
|
|
168
|
+
* Number Precision Decimals
|
|
169
|
+
* 0 2 2 ("0.00")
|
|
170
|
+
* 0.099 1 1 (0.1)
|
|
171
|
+
* 0.07 1 2
|
|
172
|
+
* 0.1 2 2
|
|
173
|
+
* 100 1 -2
|
|
174
|
+
* 100 3 0
|
|
175
|
+
* 100 4 1
|
|
176
|
+
*/
|
|
177
|
+
function getNoOfDecimalPlaces(number: number, precision: number) {
|
|
178
|
+
if (number === 0) {
|
|
179
|
+
// The precision of zero is its number of decimals
|
|
180
|
+
return precision;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const abs = Math.abs(number);
|
|
184
|
+
if (abs < 1) {
|
|
185
|
+
// Leading zeros after the decimal separator are not significant
|
|
186
|
+
const leadingZeros = getNoOfLeadingZeros(abs);
|
|
187
|
+
let decimals = precision + leadingZeros;
|
|
188
|
+
|
|
189
|
+
// Rounding may carry into the next order of magnitude, e.g. 0.099 at precision 1 is 0.1
|
|
190
|
+
if (
|
|
191
|
+
leadingZeros > 0 &&
|
|
192
|
+
Math.round(abs * Math.pow(10, decimals)) >= Math.pow(10, precision)
|
|
193
|
+
) {
|
|
194
|
+
decimals--;
|
|
195
|
+
}
|
|
196
|
+
|
|
105
197
|
return decimals;
|
|
106
|
-
} else {
|
|
107
|
-
return Math.max(getNumberOfIntegralDigits(number) + decimals, 1);
|
|
108
198
|
}
|
|
199
|
+
|
|
200
|
+
return precision - getNumberOfIntegralDigits(number);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Get the number of zeros between the decimal separator and the first significant digit of `abs` where 0 < `abs` < 1,
|
|
205
|
+
* e.g. 0.5 => 0, 0.05 => 1, 0.005 => 2
|
|
206
|
+
*/
|
|
207
|
+
function getNoOfLeadingZeros(abs: number) {
|
|
208
|
+
let leadingZeros = 0;
|
|
209
|
+
let scaled = abs * 10;
|
|
210
|
+
while (scaled < 1) {
|
|
211
|
+
scaled *= 10;
|
|
212
|
+
leadingZeros++;
|
|
213
|
+
}
|
|
214
|
+
return leadingZeros;
|
|
109
215
|
}
|
|
110
216
|
|
|
111
217
|
function getNumberOfIntegralDigits(number: number) {
|