@cj-tech-master/excelts 9.3.1 → 9.4.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.
- package/dist/browser/index.d.ts +1 -0
- package/dist/browser/index.js +2 -0
- package/dist/browser/modules/excel/cell.d.ts +18 -0
- package/dist/browser/modules/excel/cell.js +21 -0
- package/dist/browser/modules/excel/utils/cell-format.js +85 -13
- package/dist/browser/modules/excel/workbook.browser.d.ts +57 -0
- package/dist/browser/modules/excel/workbook.browser.js +49 -0
- package/dist/browser/modules/excel/xlsx/defaultnumformats.js +3 -3
- package/dist/browser/modules/formula/compile/binder.js +48 -6
- package/dist/browser/modules/formula/compile/bound-ast.d.ts +16 -2
- package/dist/browser/modules/formula/compile/bound-ast.js +1 -0
- package/dist/browser/modules/formula/compile/compiled-formula.js +41 -8
- package/dist/browser/modules/formula/functions/_shared.d.ts +19 -0
- package/dist/browser/modules/formula/functions/_shared.js +47 -0
- package/dist/browser/modules/formula/functions/conditional.js +103 -22
- package/dist/browser/modules/formula/functions/date.js +105 -23
- package/dist/browser/modules/formula/functions/dynamic-array.js +173 -69
- package/dist/browser/modules/formula/functions/engineering.d.ts +2 -2
- package/dist/browser/modules/formula/functions/engineering.js +103 -151
- package/dist/browser/modules/formula/functions/financial.js +210 -184
- package/dist/browser/modules/formula/functions/lookup.js +224 -157
- package/dist/browser/modules/formula/functions/math.d.ts +26 -0
- package/dist/browser/modules/formula/functions/math.js +249 -69
- package/dist/browser/modules/formula/functions/statistical.js +221 -171
- package/dist/browser/modules/formula/functions/text.js +112 -52
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +20 -1
- package/dist/browser/modules/formula/materialize/build-writeback-plan.js +10 -6
- package/dist/browser/modules/formula/materialize/types.d.ts +15 -0
- package/dist/browser/modules/formula/runtime/evaluator.d.ts +8 -0
- package/dist/browser/modules/formula/runtime/evaluator.js +582 -162
- package/dist/browser/modules/formula/runtime/function-registry.d.ts +5 -0
- package/dist/browser/modules/formula/runtime/function-registry.js +59 -13
- package/dist/browser/modules/formula/runtime/values.d.ts +13 -0
- package/dist/browser/modules/formula/runtime/values.js +20 -2
- package/dist/browser/modules/formula/syntax/ast.d.ts +14 -2
- package/dist/browser/modules/formula/syntax/ast.js +1 -0
- package/dist/browser/modules/formula/syntax/parser.js +29 -7
- package/dist/browser/modules/formula/syntax/token-types.d.ts +4 -0
- package/dist/browser/modules/formula/syntax/token-types.js +9 -0
- package/dist/browser/modules/formula/syntax/tokenizer.js +76 -19
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/modules/excel/cell.js +21 -0
- package/dist/cjs/modules/excel/utils/cell-format.js +85 -13
- package/dist/cjs/modules/excel/workbook.browser.js +49 -0
- package/dist/cjs/modules/excel/xlsx/defaultnumformats.js +3 -3
- package/dist/cjs/modules/formula/compile/binder.js +48 -6
- package/dist/cjs/modules/formula/compile/compiled-formula.js +41 -8
- package/dist/cjs/modules/formula/functions/_shared.js +48 -0
- package/dist/cjs/modules/formula/functions/conditional.js +103 -22
- package/dist/cjs/modules/formula/functions/date.js +104 -22
- package/dist/cjs/modules/formula/functions/dynamic-array.js +173 -69
- package/dist/cjs/modules/formula/functions/engineering.js +109 -157
- package/dist/cjs/modules/formula/functions/financial.js +209 -183
- package/dist/cjs/modules/formula/functions/lookup.js +224 -157
- package/dist/cjs/modules/formula/functions/math.js +254 -70
- package/dist/cjs/modules/formula/functions/statistical.js +222 -172
- package/dist/cjs/modules/formula/functions/text.js +112 -52
- package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +20 -1
- package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +10 -6
- package/dist/cjs/modules/formula/runtime/evaluator.js +581 -161
- package/dist/cjs/modules/formula/runtime/function-registry.js +57 -11
- package/dist/cjs/modules/formula/runtime/values.js +21 -2
- package/dist/cjs/modules/formula/syntax/parser.js +29 -7
- package/dist/cjs/modules/formula/syntax/token-types.js +9 -0
- package/dist/cjs/modules/formula/syntax/tokenizer.js +76 -19
- package/dist/esm/index.js +2 -0
- package/dist/esm/modules/excel/cell.js +21 -0
- package/dist/esm/modules/excel/utils/cell-format.js +85 -13
- package/dist/esm/modules/excel/workbook.browser.js +49 -0
- package/dist/esm/modules/excel/xlsx/defaultnumformats.js +3 -3
- package/dist/esm/modules/formula/compile/binder.js +48 -6
- package/dist/esm/modules/formula/compile/bound-ast.js +1 -0
- package/dist/esm/modules/formula/compile/compiled-formula.js +41 -8
- package/dist/esm/modules/formula/functions/_shared.js +47 -0
- package/dist/esm/modules/formula/functions/conditional.js +103 -22
- package/dist/esm/modules/formula/functions/date.js +105 -23
- package/dist/esm/modules/formula/functions/dynamic-array.js +173 -69
- package/dist/esm/modules/formula/functions/engineering.js +103 -151
- package/dist/esm/modules/formula/functions/financial.js +210 -184
- package/dist/esm/modules/formula/functions/lookup.js +224 -157
- package/dist/esm/modules/formula/functions/math.js +249 -69
- package/dist/esm/modules/formula/functions/statistical.js +221 -171
- package/dist/esm/modules/formula/functions/text.js +112 -52
- package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +20 -1
- package/dist/esm/modules/formula/materialize/build-writeback-plan.js +10 -6
- package/dist/esm/modules/formula/runtime/evaluator.js +582 -162
- package/dist/esm/modules/formula/runtime/function-registry.js +59 -13
- package/dist/esm/modules/formula/runtime/values.js +20 -2
- package/dist/esm/modules/formula/syntax/ast.js +1 -0
- package/dist/esm/modules/formula/syntax/parser.js +29 -7
- package/dist/esm/modules/formula/syntax/token-types.js +9 -0
- package/dist/esm/modules/formula/syntax/tokenizer.js +76 -19
- package/dist/iife/excelts.iife.js +1502 -1379
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +26 -26
- package/dist/types/index.d.ts +1 -0
- package/dist/types/modules/excel/cell.d.ts +18 -0
- package/dist/types/modules/excel/workbook.browser.d.ts +57 -0
- package/dist/types/modules/formula/compile/bound-ast.d.ts +16 -2
- package/dist/types/modules/formula/functions/_shared.d.ts +19 -0
- package/dist/types/modules/formula/functions/engineering.d.ts +2 -2
- package/dist/types/modules/formula/functions/math.d.ts +26 -0
- package/dist/types/modules/formula/materialize/types.d.ts +15 -0
- package/dist/types/modules/formula/runtime/evaluator.d.ts +8 -0
- package/dist/types/modules/formula/runtime/function-registry.d.ts +5 -0
- package/dist/types/modules/formula/runtime/values.d.ts +13 -0
- package/dist/types/modules/formula/syntax/ast.d.ts +14 -2
- package/dist/types/modules/formula/syntax/token-types.d.ts +4 -0
- package/package.json +1 -1
|
@@ -3,160 +3,105 @@
|
|
|
3
3
|
* Engineering Functions — Native RuntimeValue implementation.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.fnBITLSHIFT = exports.fnBITXOR = exports.fnBITOR = exports.fnBITAND = exports.fnIMCOTH = exports.fnIMSECH = exports.fnIMCSCH = exports.fnIMTANH = exports.fnIMCOSH = exports.fnIMSINH = exports.fnIMCOT = exports.fnIMSEC = exports.fnIMCSC = exports.fnIMTAN = exports.fnIMCOS = exports.fnIMSIN = exports.fnIMEXP = exports.fnIMLOG10 = exports.fnIMLOG2 = exports.fnIMLN = exports.fnIMSQRT = exports.fnIMPOWER = exports.fnIMDIV = exports.fnIMPRODUCT = exports.fnIMSUB = exports.fnIMSUM = exports.fnIMCONJUGATE = exports.fnIMARGUMENT = exports.fnIMABS = exports.fnIMAGINARY = exports.fnIMREAL = exports.fnCOMPLEX = exports.fnGESTEP = exports.fnDELTA = exports.fnBESSELY = exports.fnBESSELK = exports.fnBESSELI = exports.fnBESSELJ = exports.fnOCT2HEX = exports.fnOCT2BIN = exports.fnHEX2OCT = exports.fnHEX2BIN = exports.fnBIN2OCT = exports.fnBIN2HEX = exports.
|
|
6
|
+
exports.fnBITLSHIFT = exports.fnBITXOR = exports.fnBITOR = exports.fnBITAND = exports.fnIMCOTH = exports.fnIMSECH = exports.fnIMCSCH = exports.fnIMTANH = exports.fnIMCOSH = exports.fnIMSINH = exports.fnIMCOT = exports.fnIMSEC = exports.fnIMCSC = exports.fnIMTAN = exports.fnIMCOS = exports.fnIMSIN = exports.fnIMEXP = exports.fnIMLOG10 = exports.fnIMLOG2 = exports.fnIMLN = exports.fnIMSQRT = exports.fnIMPOWER = exports.fnIMDIV = exports.fnIMPRODUCT = exports.fnIMSUB = exports.fnIMSUM = exports.fnIMCONJUGATE = exports.fnIMARGUMENT = exports.fnIMABS = exports.fnIMAGINARY = exports.fnIMREAL = exports.fnCOMPLEX = exports.fnGESTEP = exports.fnDELTA = exports.fnBESSELY = exports.fnBESSELK = exports.fnBESSELI = exports.fnBESSELJ = exports.fnOCT2HEX = exports.fnOCT2BIN = exports.fnHEX2OCT = exports.fnHEX2BIN = exports.fnBIN2OCT = exports.fnBIN2HEX = exports.fnOCT2DEC = exports.fnHEX2DEC = exports.fnDEC2OCT = exports.fnDEC2HEX = exports.fnDEC2BIN = exports.fnBIN2DEC = void 0;
|
|
7
7
|
exports.fnBITRSHIFT = void 0;
|
|
8
8
|
const values_1 = require("../runtime/values");
|
|
9
9
|
const _shared_1 = require("./_shared");
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// Base Conversion Functions
|
|
12
12
|
// ============================================================================
|
|
13
|
-
const fnBIN2DEC = args => {
|
|
14
|
-
const err = (0, _shared_1.checkError)(args[0]);
|
|
15
|
-
if (err) {
|
|
16
|
-
return err;
|
|
17
|
-
}
|
|
18
|
-
const s = (0, values_1.toStringRV)(args[0]);
|
|
19
|
-
if (!/^[01]{1,10}$/.test(s)) {
|
|
20
|
-
return values_1.ERRORS.NUM;
|
|
21
|
-
}
|
|
22
|
-
// 10-bit two's complement
|
|
23
|
-
if (s.length === 10 && s[0] === "1") {
|
|
24
|
-
return (0, values_1.rvNumber)(parseInt(s.slice(1), 2) - 512);
|
|
25
|
-
}
|
|
26
|
-
return (0, values_1.rvNumber)(parseInt(s, 2));
|
|
27
|
-
};
|
|
13
|
+
const fnBIN2DEC = args => baseToDec(args, 2, /^[01]{1,10}$/);
|
|
28
14
|
exports.fnBIN2DEC = fnBIN2DEC;
|
|
29
|
-
const fnDEC2BIN = args =>
|
|
30
|
-
|
|
15
|
+
const fnDEC2BIN = args => decToBase(args, 2, -512, 511);
|
|
16
|
+
exports.fnDEC2BIN = fnDEC2BIN;
|
|
17
|
+
const fnDEC2HEX = args => decToBase(args, 16, -549755813888, 549755813887);
|
|
18
|
+
exports.fnDEC2HEX = fnDEC2HEX;
|
|
19
|
+
const fnDEC2OCT = args => decToBase(args, 8, -536870912, 536870911);
|
|
20
|
+
exports.fnDEC2OCT = fnDEC2OCT;
|
|
21
|
+
/**
|
|
22
|
+
* Shared implementation of `DEC2BIN`, `DEC2HEX`, `DEC2OCT`.
|
|
23
|
+
*
|
|
24
|
+
* Excel's three numeric-to-base converters differ only in the target
|
|
25
|
+
* base, the signed range they accept, and whether the output is
|
|
26
|
+
* uppercased (hex). The `places` semantics (1..10, validated only when
|
|
27
|
+
* supplied and the input is non-negative) are identical across all three.
|
|
28
|
+
*
|
|
29
|
+
* Factored here so the three converters share a single source of truth —
|
|
30
|
+
* when the Excel rules are refined (e.g. additional validations or a new
|
|
31
|
+
* `places` upper bound), all three stay in lockstep.
|
|
32
|
+
*/
|
|
33
|
+
function decToBase(args, base, minValue, maxValue) {
|
|
34
|
+
const nRV = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
31
35
|
if ((0, values_1.isError)(nRV)) {
|
|
32
36
|
return nRV;
|
|
33
37
|
}
|
|
34
38
|
// Excel's DEC→BASE family truncates toward zero, so negative fractions
|
|
35
39
|
// become `0`, not `-1` as `Math.floor` would produce.
|
|
36
40
|
const n = Math.trunc(nRV.value);
|
|
37
|
-
if (n <
|
|
41
|
+
if (n < minValue || n > maxValue) {
|
|
38
42
|
return values_1.ERRORS.NUM;
|
|
39
43
|
}
|
|
40
44
|
// `places` is only meaningful when supplied and the input is non-negative.
|
|
41
|
-
// Excel restricts it to
|
|
42
|
-
//
|
|
43
|
-
//
|
|
45
|
+
// Excel restricts it to [1, 10] and returns #NUM! outside that range.
|
|
46
|
+
// Negative inputs ignore `places` entirely — we validate it only when
|
|
47
|
+
// we've confirmed the input is non-negative.
|
|
44
48
|
const hasPlaces = args.length > 1 && args[1].kind !== 0 /* RVKind.Blank */;
|
|
45
|
-
const placesRV = hasPlaces ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
49
|
+
const placesRV = hasPlaces ? (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1])) : (0, values_1.rvNumber)(0);
|
|
46
50
|
if ((0, values_1.isError)(placesRV)) {
|
|
47
51
|
return placesRV;
|
|
48
52
|
}
|
|
49
53
|
const places = Math.trunc(placesRV.value);
|
|
54
|
+
const toUpper = base === 16;
|
|
50
55
|
if (n < 0) {
|
|
51
|
-
|
|
56
|
+
const raw = (n + Math.pow(base, 10)).toString(base);
|
|
57
|
+
return (0, values_1.rvString)(toUpper ? raw.toUpperCase() : raw);
|
|
52
58
|
}
|
|
53
59
|
if (hasPlaces && (places < 1 || places > 10)) {
|
|
54
60
|
return values_1.ERRORS.NUM;
|
|
55
61
|
}
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (err) {
|
|
63
|
-
return err;
|
|
64
|
-
}
|
|
65
|
-
const s = (0, values_1.toStringRV)(args[0]);
|
|
66
|
-
if (!/^[0-9A-Fa-f]{1,10}$/.test(s)) {
|
|
62
|
+
const raw = n.toString(base);
|
|
63
|
+
const result = toUpper ? raw.toUpperCase() : raw;
|
|
64
|
+
// When `places` is supplied but smaller than the natural representation,
|
|
65
|
+
// Excel returns `#NUM!` rather than silently ignoring the width. `padStart`
|
|
66
|
+
// alone would leave the wider result unchanged — a soft deviation.
|
|
67
|
+
if (hasPlaces && places > 0 && result.length > places) {
|
|
67
68
|
return values_1.ERRORS.NUM;
|
|
68
69
|
}
|
|
69
|
-
const num = parseInt(s, 16);
|
|
70
|
-
// 10-digit hex: 40-bit two's complement
|
|
71
|
-
if (s.length === 10 && parseInt(s[0], 16) >= 8) {
|
|
72
|
-
return (0, values_1.rvNumber)(num - Math.pow(16, 10));
|
|
73
|
-
}
|
|
74
|
-
return (0, values_1.rvNumber)(num);
|
|
75
|
-
};
|
|
76
|
-
exports.fnHEX2DEC = fnHEX2DEC;
|
|
77
|
-
const fnDEC2HEX = args => {
|
|
78
|
-
const nRV = (0, values_1.toNumberRV)(args[0]);
|
|
79
|
-
if ((0, values_1.isError)(nRV)) {
|
|
80
|
-
return nRV;
|
|
81
|
-
}
|
|
82
|
-
// Excel's DEC→BASE family truncates toward zero, so negative fractions
|
|
83
|
-
// become `0`, not `-1` as `Math.floor` would produce.
|
|
84
|
-
const n = Math.trunc(nRV.value);
|
|
85
|
-
// Excel rejects anything outside the 40-bit signed range.
|
|
86
|
-
// Without this check, inputs like 1e14 produce a 13-digit hex string
|
|
87
|
-
// and inputs below -2^39 wrap into spurious positive values prefixed
|
|
88
|
-
// with `-`. See R6-P0-1.
|
|
89
|
-
if (n < -549755813888 || n > 549755813887) {
|
|
90
|
-
return values_1.ERRORS.NUM;
|
|
91
|
-
}
|
|
92
|
-
// Same places semantics as DEC2BIN: validate only when `places` is
|
|
93
|
-
// supplied and the input is non-negative; Excel ignores `places` for
|
|
94
|
-
// negative numbers.
|
|
95
|
-
const hasPlaces = args.length > 1 && args[1].kind !== 0 /* RVKind.Blank */;
|
|
96
|
-
const placesRV = hasPlaces ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
97
|
-
if ((0, values_1.isError)(placesRV)) {
|
|
98
|
-
return placesRV;
|
|
99
|
-
}
|
|
100
|
-
const places = Math.trunc(placesRV.value);
|
|
101
|
-
if (n < 0) {
|
|
102
|
-
return (0, values_1.rvString)((n + Math.pow(16, 10)).toString(16).toUpperCase());
|
|
103
|
-
}
|
|
104
|
-
if (hasPlaces && (places < 1 || places > 10)) {
|
|
105
|
-
return values_1.ERRORS.NUM;
|
|
106
|
-
}
|
|
107
|
-
const result = n.toString(16).toUpperCase();
|
|
108
70
|
return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
71
|
+
}
|
|
72
|
+
const fnHEX2DEC = args => baseToDec(args, 16, /^[0-9A-Fa-f]{1,10}$/);
|
|
73
|
+
exports.fnHEX2DEC = fnHEX2DEC;
|
|
74
|
+
const fnOCT2DEC = args => baseToDec(args, 8, /^[0-7]{1,10}$/);
|
|
75
|
+
exports.fnOCT2DEC = fnOCT2DEC;
|
|
76
|
+
/**
|
|
77
|
+
* Shared implementation of `BIN2DEC`, `OCT2DEC`, `HEX2DEC`.
|
|
78
|
+
*
|
|
79
|
+
* Each source base has the same "string of up to 10 digits, 10th digit
|
|
80
|
+
* sets the sign bit for two's-complement" semantics. The only
|
|
81
|
+
* differences are the allowed digit alphabet (passed as `pattern`) and
|
|
82
|
+
* the base (passed as `base`). The `isNegativeMsd` helper detects the
|
|
83
|
+
* sign bit by re-parsing the top digit; it works for binary (MSD=1),
|
|
84
|
+
* octal (MSD>=4) and hex (MSD>=8).
|
|
85
|
+
*/
|
|
86
|
+
function baseToDec(args, base, pattern) {
|
|
112
87
|
const err = (0, _shared_1.checkError)(args[0]);
|
|
113
88
|
if (err) {
|
|
114
89
|
return err;
|
|
115
90
|
}
|
|
116
|
-
const s = (0, values_1.toStringRV)(args[0]);
|
|
117
|
-
if (
|
|
91
|
+
const s = (0, values_1.toStringRV)((0, values_1.topLeft)(args[0]));
|
|
92
|
+
if (!pattern.test(s)) {
|
|
118
93
|
return values_1.ERRORS.NUM;
|
|
119
94
|
}
|
|
120
|
-
const num = parseInt(s,
|
|
121
|
-
|
|
122
|
-
|
|
95
|
+
const num = parseInt(s, base);
|
|
96
|
+
// 10-digit form triggers two's-complement interpretation. The sign bit
|
|
97
|
+
// is the top bit of the top digit — for binary that's the literal MSD,
|
|
98
|
+
// for octal it's `>= 4`, for hex it's `>= 8`. We compute the threshold
|
|
99
|
+
// from the base instead of hard-coding it.
|
|
100
|
+
if (s.length === 10 && parseInt(s[0], base) >= base / 2) {
|
|
101
|
+
return (0, values_1.rvNumber)(num - Math.pow(base, 10));
|
|
123
102
|
}
|
|
124
103
|
return (0, values_1.rvNumber)(num);
|
|
125
|
-
}
|
|
126
|
-
exports.fnOCT2DEC = fnOCT2DEC;
|
|
127
|
-
const fnDEC2OCT = args => {
|
|
128
|
-
const nRV = (0, values_1.toNumberRV)(args[0]);
|
|
129
|
-
if ((0, values_1.isError)(nRV)) {
|
|
130
|
-
return nRV;
|
|
131
|
-
}
|
|
132
|
-
// Excel's DEC→BASE family truncates toward zero, so negative fractions
|
|
133
|
-
// become `0`, not `-1` as `Math.floor` would produce.
|
|
134
|
-
const n = Math.trunc(nRV.value);
|
|
135
|
-
// Excel's DEC2OCT range is the 30-bit signed range (-2^29 .. 2^29-1).
|
|
136
|
-
// Values outside this range are #NUM! in Excel; we silently wrapped
|
|
137
|
-
// into bogus sign-prefixed strings without this guard. See R6-P0-1.
|
|
138
|
-
if (n < -536870912 || n > 536870911) {
|
|
139
|
-
return values_1.ERRORS.NUM;
|
|
140
|
-
}
|
|
141
|
-
// Same places semantics as DEC2BIN: validate only when `places` is
|
|
142
|
-
// supplied and the input is non-negative; Excel ignores `places` for
|
|
143
|
-
// negative numbers.
|
|
144
|
-
const hasPlaces = args.length > 1 && args[1].kind !== 0 /* RVKind.Blank */;
|
|
145
|
-
const placesRV = hasPlaces ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
146
|
-
if ((0, values_1.isError)(placesRV)) {
|
|
147
|
-
return placesRV;
|
|
148
|
-
}
|
|
149
|
-
const places = Math.trunc(placesRV.value);
|
|
150
|
-
if (n < 0) {
|
|
151
|
-
return (0, values_1.rvString)((n + Math.pow(8, 10)).toString(8));
|
|
152
|
-
}
|
|
153
|
-
if (hasPlaces && (places < 1 || places > 10)) {
|
|
154
|
-
return values_1.ERRORS.NUM;
|
|
155
|
-
}
|
|
156
|
-
const result = n.toString(8);
|
|
157
|
-
return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
|
|
158
|
-
};
|
|
159
|
-
exports.fnDEC2OCT = fnDEC2OCT;
|
|
104
|
+
}
|
|
160
105
|
/**
|
|
161
106
|
* Generic helper for the X2Y conversion family (BIN2HEX, HEX2BIN, …).
|
|
162
107
|
*
|
|
@@ -172,13 +117,13 @@ function convertBase(args, parseNInput, format) {
|
|
|
172
117
|
if (err) {
|
|
173
118
|
return err;
|
|
174
119
|
}
|
|
175
|
-
const s = (0, values_1.toStringRV)(args[0]);
|
|
120
|
+
const s = (0, values_1.toStringRV)((0, values_1.topLeft)(args[0]));
|
|
176
121
|
const n = parseNInput(s);
|
|
177
122
|
if (typeof n !== "number") {
|
|
178
123
|
return n;
|
|
179
124
|
}
|
|
180
125
|
const hasPlaces = args.length > 1 && args[1].kind !== 0 /* RVKind.Blank */;
|
|
181
|
-
const placesRV = hasPlaces ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
126
|
+
const placesRV = hasPlaces ? (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1])) : (0, values_1.rvNumber)(0);
|
|
182
127
|
if ((0, values_1.isError)(placesRV)) {
|
|
183
128
|
return placesRV;
|
|
184
129
|
}
|
|
@@ -217,6 +162,11 @@ function formatToBase(n, base, maxDigits, places, hasPlaces) {
|
|
|
217
162
|
return values_1.ERRORS.NUM;
|
|
218
163
|
}
|
|
219
164
|
const result = n.toString(base).toUpperCase();
|
|
165
|
+
// `places` smaller than the natural representation is a #NUM! in Excel —
|
|
166
|
+
// `padStart` alone would silently emit the wider form.
|
|
167
|
+
if (hasPlaces && places > 0 && result.length > places) {
|
|
168
|
+
return values_1.ERRORS.NUM;
|
|
169
|
+
}
|
|
220
170
|
return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
|
|
221
171
|
}
|
|
222
172
|
const fnBIN2HEX = args => convertBase(args, parseBinInput, (n, places, hasPlaces) => formatToBase(n, 16, 10, places, hasPlaces));
|
|
@@ -478,11 +428,11 @@ function besselK(n, x) {
|
|
|
478
428
|
}
|
|
479
429
|
/** Common validation + dispatch for the four BESSEL* functions. */
|
|
480
430
|
function bessel(args, compute, allowZeroX) {
|
|
481
|
-
const xRV = (0, values_1.toNumberRV)(args[0]);
|
|
431
|
+
const xRV = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
482
432
|
if ((0, values_1.isError)(xRV)) {
|
|
483
433
|
return xRV;
|
|
484
434
|
}
|
|
485
|
-
const nRV = (0, values_1.toNumberRV)(args[1]);
|
|
435
|
+
const nRV = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1]));
|
|
486
436
|
if ((0, values_1.isError)(nRV)) {
|
|
487
437
|
return nRV;
|
|
488
438
|
}
|
|
@@ -511,11 +461,11 @@ exports.fnBESSELK = fnBESSELK;
|
|
|
511
461
|
const fnBESSELY = args => bessel(args, besselY, false);
|
|
512
462
|
exports.fnBESSELY = fnBESSELY;
|
|
513
463
|
const fnDELTA = args => {
|
|
514
|
-
const n1 = (0, values_1.toNumberRV)(args[0]);
|
|
464
|
+
const n1 = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
515
465
|
if ((0, values_1.isError)(n1)) {
|
|
516
466
|
return n1;
|
|
517
467
|
}
|
|
518
|
-
const n2 = args.length > 1 ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
468
|
+
const n2 = args.length > 1 ? (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1])) : (0, values_1.rvNumber)(0);
|
|
519
469
|
if ((0, values_1.isError)(n2)) {
|
|
520
470
|
return n2;
|
|
521
471
|
}
|
|
@@ -523,11 +473,11 @@ const fnDELTA = args => {
|
|
|
523
473
|
};
|
|
524
474
|
exports.fnDELTA = fnDELTA;
|
|
525
475
|
const fnGESTEP = args => {
|
|
526
|
-
const n = (0, values_1.toNumberRV)(args[0]);
|
|
476
|
+
const n = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
527
477
|
if ((0, values_1.isError)(n)) {
|
|
528
478
|
return n;
|
|
529
479
|
}
|
|
530
|
-
const step = args.length > 1 ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
480
|
+
const step = args.length > 1 ? (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1])) : (0, values_1.rvNumber)(0);
|
|
531
481
|
if ((0, values_1.isError)(step)) {
|
|
532
482
|
return step;
|
|
533
483
|
}
|
|
@@ -610,22 +560,24 @@ function formatComplex(re, im, suffix = "i") {
|
|
|
610
560
|
return re + imStr;
|
|
611
561
|
}
|
|
612
562
|
const fnCOMPLEX = args => {
|
|
613
|
-
const re = (0, values_1.toNumberRV)(args[0]);
|
|
563
|
+
const re = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
614
564
|
if ((0, values_1.isError)(re)) {
|
|
615
565
|
return re;
|
|
616
566
|
}
|
|
617
|
-
const im = (0, values_1.toNumberRV)(args[1]);
|
|
567
|
+
const im = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1]));
|
|
618
568
|
if ((0, values_1.isError)(im)) {
|
|
619
569
|
return im;
|
|
620
570
|
}
|
|
621
571
|
let suffix = "i";
|
|
622
|
-
if (args.length > 2) {
|
|
572
|
+
if (args.length > 2 && args[2].kind !== 0 /* RVKind.Blank */) {
|
|
623
573
|
const e2 = (0, _shared_1.checkError)(args[2]);
|
|
624
574
|
if (e2) {
|
|
625
575
|
return e2;
|
|
626
576
|
}
|
|
627
|
-
suffix = (0, values_1.toStringRV)(args[2]);
|
|
577
|
+
suffix = (0, values_1.toStringRV)((0, values_1.topLeft)(args[2]));
|
|
628
578
|
}
|
|
579
|
+
// Blank 3rd arg → default "i". Previously a blank coerced to empty
|
|
580
|
+
// string then tripped the `suffix !== "i"` validation.
|
|
629
581
|
if (suffix !== "i" && suffix !== "j") {
|
|
630
582
|
return values_1.ERRORS.VALUE;
|
|
631
583
|
}
|
|
@@ -637,7 +589,7 @@ const fnIMREAL = args => {
|
|
|
637
589
|
if (err) {
|
|
638
590
|
return err;
|
|
639
591
|
}
|
|
640
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
592
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
641
593
|
return c ? (0, values_1.rvNumber)(c[0]) : values_1.ERRORS.NUM;
|
|
642
594
|
};
|
|
643
595
|
exports.fnIMREAL = fnIMREAL;
|
|
@@ -646,7 +598,7 @@ const fnIMAGINARY = args => {
|
|
|
646
598
|
if (err) {
|
|
647
599
|
return err;
|
|
648
600
|
}
|
|
649
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
601
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
650
602
|
return c ? (0, values_1.rvNumber)(c[1]) : values_1.ERRORS.NUM;
|
|
651
603
|
};
|
|
652
604
|
exports.fnIMAGINARY = fnIMAGINARY;
|
|
@@ -655,7 +607,7 @@ const fnIMABS = args => {
|
|
|
655
607
|
if (err) {
|
|
656
608
|
return err;
|
|
657
609
|
}
|
|
658
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
610
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
659
611
|
if (!c) {
|
|
660
612
|
return values_1.ERRORS.NUM;
|
|
661
613
|
}
|
|
@@ -667,7 +619,7 @@ const fnIMARGUMENT = args => {
|
|
|
667
619
|
if (err) {
|
|
668
620
|
return err;
|
|
669
621
|
}
|
|
670
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
622
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
671
623
|
if (!c) {
|
|
672
624
|
return values_1.ERRORS.NUM;
|
|
673
625
|
}
|
|
@@ -682,7 +634,7 @@ const fnIMCONJUGATE = args => {
|
|
|
682
634
|
if (err) {
|
|
683
635
|
return err;
|
|
684
636
|
}
|
|
685
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
637
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
686
638
|
if (!c) {
|
|
687
639
|
return values_1.ERRORS.NUM;
|
|
688
640
|
}
|
|
@@ -764,8 +716,8 @@ const fnIMSUB = args => {
|
|
|
764
716
|
if (e1) {
|
|
765
717
|
return e1;
|
|
766
718
|
}
|
|
767
|
-
const c1 = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
768
|
-
const c2 = parseComplex((0, values_1.toStringRV)(args[1]));
|
|
719
|
+
const c1 = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
720
|
+
const c2 = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[1])));
|
|
769
721
|
if (!c1 || !c2) {
|
|
770
722
|
return values_1.ERRORS.NUM;
|
|
771
723
|
}
|
|
@@ -802,8 +754,8 @@ const fnIMDIV = args => {
|
|
|
802
754
|
if (e1) {
|
|
803
755
|
return e1;
|
|
804
756
|
}
|
|
805
|
-
const c1 = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
806
|
-
const c2 = parseComplex((0, values_1.toStringRV)(args[1]));
|
|
757
|
+
const c1 = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
758
|
+
const c2 = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[1])));
|
|
807
759
|
if (!c1 || !c2) {
|
|
808
760
|
return values_1.ERRORS.NUM;
|
|
809
761
|
}
|
|
@@ -824,11 +776,11 @@ const fnIMPOWER = args => {
|
|
|
824
776
|
if (err) {
|
|
825
777
|
return err;
|
|
826
778
|
}
|
|
827
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
779
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
828
780
|
if (!c) {
|
|
829
781
|
return values_1.ERRORS.NUM;
|
|
830
782
|
}
|
|
831
|
-
const n = (0, values_1.toNumberRV)(args[1]);
|
|
783
|
+
const n = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1]));
|
|
832
784
|
if ((0, values_1.isError)(n)) {
|
|
833
785
|
return n;
|
|
834
786
|
}
|
|
@@ -843,7 +795,7 @@ const fnIMSQRT = args => {
|
|
|
843
795
|
if (err) {
|
|
844
796
|
return err;
|
|
845
797
|
}
|
|
846
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
798
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
847
799
|
if (!c) {
|
|
848
800
|
return values_1.ERRORS.NUM;
|
|
849
801
|
}
|
|
@@ -858,7 +810,7 @@ const fnIMLN = args => {
|
|
|
858
810
|
if (err) {
|
|
859
811
|
return err;
|
|
860
812
|
}
|
|
861
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
813
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
862
814
|
if (!c) {
|
|
863
815
|
return values_1.ERRORS.NUM;
|
|
864
816
|
}
|
|
@@ -874,7 +826,7 @@ const fnIMLOG2 = args => {
|
|
|
874
826
|
if (err) {
|
|
875
827
|
return err;
|
|
876
828
|
}
|
|
877
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
829
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
878
830
|
if (!c) {
|
|
879
831
|
return values_1.ERRORS.NUM;
|
|
880
832
|
}
|
|
@@ -891,7 +843,7 @@ const fnIMLOG10 = args => {
|
|
|
891
843
|
if (err) {
|
|
892
844
|
return err;
|
|
893
845
|
}
|
|
894
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
846
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
895
847
|
if (!c) {
|
|
896
848
|
return values_1.ERRORS.NUM;
|
|
897
849
|
}
|
|
@@ -908,7 +860,7 @@ const fnIMEXP = args => {
|
|
|
908
860
|
if (err) {
|
|
909
861
|
return err;
|
|
910
862
|
}
|
|
911
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
863
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
912
864
|
if (!c) {
|
|
913
865
|
return values_1.ERRORS.NUM;
|
|
914
866
|
}
|
|
@@ -921,7 +873,7 @@ const fnIMSIN = args => {
|
|
|
921
873
|
if (err) {
|
|
922
874
|
return err;
|
|
923
875
|
}
|
|
924
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
876
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
925
877
|
if (!c) {
|
|
926
878
|
return values_1.ERRORS.NUM;
|
|
927
879
|
}
|
|
@@ -933,7 +885,7 @@ const fnIMCOS = args => {
|
|
|
933
885
|
if (err) {
|
|
934
886
|
return err;
|
|
935
887
|
}
|
|
936
|
-
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
888
|
+
const c = parseComplex((0, values_1.toStringRV)((0, values_1.topLeft)(args[0])));
|
|
937
889
|
if (!c) {
|
|
938
890
|
return values_1.ERRORS.NUM;
|
|
939
891
|
}
|
|
@@ -1074,11 +1026,11 @@ function validateBitOperand(v) {
|
|
|
1074
1026
|
return v;
|
|
1075
1027
|
}
|
|
1076
1028
|
const fnBITAND = args => {
|
|
1077
|
-
const a = (0, values_1.toNumberRV)(args[0]);
|
|
1029
|
+
const a = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
1078
1030
|
if ((0, values_1.isError)(a)) {
|
|
1079
1031
|
return a;
|
|
1080
1032
|
}
|
|
1081
|
-
const b = (0, values_1.toNumberRV)(args[1]);
|
|
1033
|
+
const b = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1]));
|
|
1082
1034
|
if ((0, values_1.isError)(b)) {
|
|
1083
1035
|
return b;
|
|
1084
1036
|
}
|
|
@@ -1094,11 +1046,11 @@ const fnBITAND = args => {
|
|
|
1094
1046
|
};
|
|
1095
1047
|
exports.fnBITAND = fnBITAND;
|
|
1096
1048
|
const fnBITOR = args => {
|
|
1097
|
-
const a = (0, values_1.toNumberRV)(args[0]);
|
|
1049
|
+
const a = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
1098
1050
|
if ((0, values_1.isError)(a)) {
|
|
1099
1051
|
return a;
|
|
1100
1052
|
}
|
|
1101
|
-
const b = (0, values_1.toNumberRV)(args[1]);
|
|
1053
|
+
const b = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1]));
|
|
1102
1054
|
if ((0, values_1.isError)(b)) {
|
|
1103
1055
|
return b;
|
|
1104
1056
|
}
|
|
@@ -1114,11 +1066,11 @@ const fnBITOR = args => {
|
|
|
1114
1066
|
};
|
|
1115
1067
|
exports.fnBITOR = fnBITOR;
|
|
1116
1068
|
const fnBITXOR = args => {
|
|
1117
|
-
const a = (0, values_1.toNumberRV)(args[0]);
|
|
1069
|
+
const a = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
1118
1070
|
if ((0, values_1.isError)(a)) {
|
|
1119
1071
|
return a;
|
|
1120
1072
|
}
|
|
1121
|
-
const b = (0, values_1.toNumberRV)(args[1]);
|
|
1073
|
+
const b = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1]));
|
|
1122
1074
|
if ((0, values_1.isError)(b)) {
|
|
1123
1075
|
return b;
|
|
1124
1076
|
}
|
|
@@ -1134,11 +1086,11 @@ const fnBITXOR = args => {
|
|
|
1134
1086
|
};
|
|
1135
1087
|
exports.fnBITXOR = fnBITXOR;
|
|
1136
1088
|
const fnBITLSHIFT = args => {
|
|
1137
|
-
const num = (0, values_1.toNumberRV)(args[0]);
|
|
1089
|
+
const num = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
1138
1090
|
if ((0, values_1.isError)(num)) {
|
|
1139
1091
|
return num;
|
|
1140
1092
|
}
|
|
1141
|
-
const shift = (0, values_1.toNumberRV)(args[1]);
|
|
1093
|
+
const shift = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1]));
|
|
1142
1094
|
if ((0, values_1.isError)(shift)) {
|
|
1143
1095
|
return shift;
|
|
1144
1096
|
}
|
|
@@ -1158,11 +1110,11 @@ const fnBITLSHIFT = args => {
|
|
|
1158
1110
|
};
|
|
1159
1111
|
exports.fnBITLSHIFT = fnBITLSHIFT;
|
|
1160
1112
|
const fnBITRSHIFT = args => {
|
|
1161
|
-
const num = (0, values_1.toNumberRV)(args[0]);
|
|
1113
|
+
const num = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[0]));
|
|
1162
1114
|
if ((0, values_1.isError)(num)) {
|
|
1163
1115
|
return num;
|
|
1164
1116
|
}
|
|
1165
|
-
const shift = (0, values_1.toNumberRV)(args[1]);
|
|
1117
|
+
const shift = (0, values_1.toNumberRV)((0, values_1.topLeft)(args[1]));
|
|
1166
1118
|
if ((0, values_1.isError)(shift)) {
|
|
1167
1119
|
return shift;
|
|
1168
1120
|
}
|