UNPKG

9.34 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5Object.defineProperty(exports, "__esModule", {
6 value: true
7});
8exports.NumberDecimal = exports.BigIntDecimal = void 0;
9exports.default = getMiniDecimal;
10exports.toFixed = toFixed;
11
12var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
14var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
15
16var _numberUtil = require("./numberUtil");
17
18var _supportUtil = require("./supportUtil");
19
20/* eslint-disable max-classes-per-file */
21
22/**
23 * We can remove this when IE not support anymore
24 */
25var NumberDecimal = /*#__PURE__*/function () {
26 function NumberDecimal(value) {
27 (0, _classCallCheck2.default)(this, NumberDecimal);
28 this.origin = '';
29 this.number = void 0;
30 this.empty = void 0;
31
32 if (!value && value !== 0 || !String(value).trim()) {
33 this.empty = true;
34 return;
35 }
36
37 this.origin = String(value);
38 this.number = Number(value);
39 }
40
41 (0, _createClass2.default)(NumberDecimal, [{
42 key: "negate",
43 value: function negate() {
44 return new NumberDecimal(-this.toNumber());
45 }
46 }, {
47 key: "add",
48 value: function add(value) {
49 if (this.isInvalidate()) {
50 return new NumberDecimal(value);
51 }
52
53 var target = Number(value);
54
55 if (Number.isNaN(target)) {
56 return this;
57 }
58
59 var number = this.number + target; // [Legacy] Back to safe integer
60
61 if (number > Number.MAX_SAFE_INTEGER) {
62 return new NumberDecimal(Number.MAX_SAFE_INTEGER);
63 }
64
65 if (number < Number.MIN_SAFE_INTEGER) {
66 return new NumberDecimal(Number.MIN_SAFE_INTEGER);
67 }
68
69 var maxPrecision = Math.max((0, _numberUtil.getNumberPrecision)(this.number), (0, _numberUtil.getNumberPrecision)(target));
70 return new NumberDecimal(number.toFixed(maxPrecision));
71 }
72 }, {
73 key: "isEmpty",
74 value: function isEmpty() {
75 return this.empty;
76 }
77 }, {
78 key: "isNaN",
79 value: function isNaN() {
80 return Number.isNaN(this.number);
81 }
82 }, {
83 key: "isInvalidate",
84 value: function isInvalidate() {
85 return this.isEmpty() || this.isNaN();
86 }
87 }, {
88 key: "equals",
89 value: function equals(target) {
90 return this.toNumber() === (target === null || target === void 0 ? void 0 : target.toNumber());
91 }
92 }, {
93 key: "lessEquals",
94 value: function lessEquals(target) {
95 return this.add(target.negate().toString()).toNumber() <= 0;
96 }
97 }, {
98 key: "toNumber",
99 value: function toNumber() {
100 return this.number;
101 }
102 }, {
103 key: "toString",
104 value: function toString() {
105 var safe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
106
107 if (!safe) {
108 return this.origin;
109 }
110
111 if (this.isInvalidate()) {
112 return '';
113 }
114
115 return (0, _numberUtil.num2str)(this.number);
116 }
117 }]);
118 return NumberDecimal;
119}();
120
121exports.NumberDecimal = NumberDecimal;
122
123var BigIntDecimal = /*#__PURE__*/function () {
124 /** BigInt will convert `0009` to `9`. We need record the len of decimal */
125 function BigIntDecimal(value) {
126 (0, _classCallCheck2.default)(this, BigIntDecimal);
127 this.origin = '';
128 this.negative = void 0;
129 this.integer = void 0;
130 this.decimal = void 0;
131 this.decimalLen = void 0;
132 this.empty = void 0;
133 this.nan = void 0;
134
135 if (!value && value !== 0 || !String(value).trim()) {
136 this.empty = true;
137 return;
138 }
139
140 this.origin = String(value); // Act like Number convert
141
142 if (value === '-') {
143 this.nan = true;
144 return;
145 }
146
147 var mergedValue = value; // We need convert back to Number since it require `toFixed` to handle this
148
149 if ((0, _numberUtil.isE)(mergedValue)) {
150 mergedValue = Number(mergedValue);
151 }
152
153 mergedValue = typeof mergedValue === 'string' ? mergedValue : (0, _numberUtil.num2str)(mergedValue);
154
155 if ((0, _numberUtil.validateNumber)(mergedValue)) {
156 var trimRet = (0, _numberUtil.trimNumber)(mergedValue);
157 this.negative = trimRet.negative;
158 var numbers = trimRet.trimStr.split('.');
159 this.integer = BigInt(numbers[0]);
160 var decimalStr = numbers[1] || '0';
161 this.decimal = BigInt(decimalStr);
162 this.decimalLen = decimalStr.length;
163 } else {
164 this.nan = true;
165 }
166 }
167
168 (0, _createClass2.default)(BigIntDecimal, [{
169 key: "getMark",
170 value: function getMark() {
171 return this.negative ? '-' : '';
172 }
173 }, {
174 key: "getIntegerStr",
175 value: function getIntegerStr() {
176 return this.integer.toString();
177 }
178 }, {
179 key: "getDecimalStr",
180 value: function getDecimalStr() {
181 return this.decimal.toString().padStart(this.decimalLen, '0');
182 }
183 /**
184 * Align BigIntDecimal with same decimal length. e.g. 12.3 + 5 = 1230000
185 * This is used for add function only.
186 */
187
188 }, {
189 key: "alignDecimal",
190 value: function alignDecimal(decimalLength) {
191 var str = "".concat(this.getMark()).concat(this.getIntegerStr()).concat(this.getDecimalStr().padEnd(decimalLength, '0'));
192 return BigInt(str);
193 }
194 }, {
195 key: "negate",
196 value: function negate() {
197 var clone = new BigIntDecimal(this.toString());
198 clone.negative = !clone.negative;
199 return clone;
200 }
201 }, {
202 key: "add",
203 value: function add(value) {
204 if (this.isInvalidate()) {
205 return new BigIntDecimal(value);
206 }
207
208 var offset = new BigIntDecimal(value);
209
210 if (offset.isInvalidate()) {
211 return this;
212 }
213
214 var maxDecimalLength = Math.max(this.getDecimalStr().length, offset.getDecimalStr().length);
215 var myAlignedDecimal = this.alignDecimal(maxDecimalLength);
216 var offsetAlignedDecimal = offset.alignDecimal(maxDecimalLength);
217 var valueStr = (myAlignedDecimal + offsetAlignedDecimal).toString(); // We need fill string length back to `maxDecimalLength` to avoid parser failed
218
219 var _trimNumber = (0, _numberUtil.trimNumber)(valueStr),
220 negativeStr = _trimNumber.negativeStr,
221 trimStr = _trimNumber.trimStr;
222
223 var hydrateValueStr = "".concat(negativeStr).concat(trimStr.padStart(maxDecimalLength + 1, '0'));
224 return new BigIntDecimal("".concat(hydrateValueStr.slice(0, -maxDecimalLength), ".").concat(hydrateValueStr.slice(-maxDecimalLength)));
225 }
226 }, {
227 key: "isEmpty",
228 value: function isEmpty() {
229 return this.empty;
230 }
231 }, {
232 key: "isNaN",
233 value: function isNaN() {
234 return this.nan;
235 }
236 }, {
237 key: "isInvalidate",
238 value: function isInvalidate() {
239 return this.isEmpty() || this.isNaN();
240 }
241 }, {
242 key: "equals",
243 value: function equals(target) {
244 return this.toString() === (target === null || target === void 0 ? void 0 : target.toString());
245 }
246 }, {
247 key: "lessEquals",
248 value: function lessEquals(target) {
249 return this.add(target.negate().toString()).toNumber() <= 0;
250 }
251 }, {
252 key: "toNumber",
253 value: function toNumber() {
254 if (this.isNaN()) {
255 return NaN;
256 }
257
258 return Number(this.toString());
259 }
260 }, {
261 key: "toString",
262 value: function toString() {
263 var safe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
264
265 if (!safe) {
266 return this.origin;
267 }
268
269 if (this.isInvalidate()) {
270 return '';
271 }
272
273 return (0, _numberUtil.trimNumber)("".concat(this.getMark()).concat(this.getIntegerStr(), ".").concat(this.getDecimalStr())).fullStr;
274 }
275 }]);
276 return BigIntDecimal;
277}();
278
279exports.BigIntDecimal = BigIntDecimal;
280
281function getMiniDecimal(value) {
282 // We use BigInt here.
283 // Will fallback to Number if not support.
284 if ((0, _supportUtil.supportBigInt)()) {
285 return new BigIntDecimal(value);
286 }
287
288 return new NumberDecimal(value);
289}
290/**
291 * Align the logic of toFixed to around like 1.5 => 2.
292 * If set `cutOnly`, will just remove the over decimal part.
293 */
294
295
296function toFixed(numStr, separatorStr, precision) {
297 var cutOnly = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
298
299 if (numStr === '') {
300 return '';
301 }
302
303 var _trimNumber2 = (0, _numberUtil.trimNumber)(numStr),
304 negativeStr = _trimNumber2.negativeStr,
305 integerStr = _trimNumber2.integerStr,
306 decimalStr = _trimNumber2.decimalStr;
307
308 var precisionDecimalStr = "".concat(separatorStr).concat(decimalStr);
309 var numberWithoutDecimal = "".concat(negativeStr).concat(integerStr);
310
311 if (precision >= 0) {
312 // We will get last + 1 number to check if need advanced number
313 var advancedNum = Number(decimalStr[precision]);
314
315 if (advancedNum >= 5 && !cutOnly) {
316 var advancedDecimal = getMiniDecimal(numStr).add("".concat(negativeStr, "0.").concat('0'.repeat(precision)).concat(10 - advancedNum));
317 return toFixed(advancedDecimal.toString(), separatorStr, precision, cutOnly);
318 }
319
320 if (precision === 0) {
321 return numberWithoutDecimal;
322 }
323
324 return "".concat(numberWithoutDecimal).concat(separatorStr).concat(decimalStr.padEnd(precision, '0').slice(0, precision));
325 }
326
327 if (precisionDecimalStr === '.0') {
328 return numberWithoutDecimal;
329 }
330
331 return "".concat(numberWithoutDecimal).concat(precisionDecimalStr);
332}
\No newline at end of file