@cj-tech-master/excelts 9.2.1 → 9.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.
- package/README.md +25 -2
- package/README_zh.md +29 -6
- package/dist/browser/index.browser.d.ts +1 -1
- package/dist/browser/index.browser.js +4 -0
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +4 -0
- package/dist/browser/modules/excel/cell.d.ts +17 -3
- package/dist/browser/modules/excel/cell.js +170 -22
- package/dist/browser/modules/excel/defined-names.d.ts +96 -1
- package/dist/browser/modules/excel/defined-names.js +411 -21
- package/dist/browser/modules/excel/image.d.ts +11 -0
- package/dist/browser/modules/excel/image.js +24 -1
- package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/browser/modules/excel/table.js +15 -2
- package/dist/browser/modules/excel/types.d.ts +133 -2
- package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/browser/modules/excel/utils/col-cache.js +15 -0
- package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
- package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/browser/modules/excel/workbook.browser.js +318 -34
- package/dist/browser/modules/excel/workbook.d.ts +1 -1
- package/dist/browser/modules/excel/worksheet.d.ts +3 -1
- package/dist/browser/modules/excel/worksheet.js +21 -2
- package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/browser/modules/formula/compile/address-utils.js +83 -0
- package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
- package/dist/browser/modules/formula/compile/binder.js +487 -0
- package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
- package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
- package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/browser/modules/formula/functions/_date-context.js +29 -0
- package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/browser/modules/formula/functions/_shared.js +381 -0
- package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/browser/modules/formula/functions/conditional.js +343 -0
- package/dist/browser/modules/formula/functions/database.d.ts +37 -0
- package/dist/browser/modules/formula/functions/database.js +274 -0
- package/dist/browser/modules/formula/functions/date.d.ts +61 -0
- package/dist/browser/modules/formula/functions/date.js +855 -0
- package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/browser/modules/formula/functions/engineering.js +1128 -0
- package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
- package/dist/browser/modules/formula/functions/financial.js +2296 -0
- package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/browser/modules/formula/functions/lookup.js +886 -0
- package/dist/browser/modules/formula/functions/math.d.ts +114 -0
- package/dist/browser/modules/formula/functions/math.js +1406 -0
- package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/browser/modules/formula/functions/statistical.js +3390 -0
- package/dist/browser/modules/formula/functions/text.d.ts +86 -0
- package/dist/browser/modules/formula/functions/text.js +1845 -0
- package/dist/browser/modules/formula/host-registry.d.ts +53 -0
- package/dist/browser/modules/formula/host-registry.js +69 -0
- package/dist/browser/modules/formula/index.d.ts +39 -0
- package/dist/browser/modules/formula/index.js +49 -0
- package/dist/browser/modules/formula/install.d.ts +62 -0
- package/dist/browser/modules/formula/install.js +88 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
- package/dist/browser/modules/formula/materialize/types.js +29 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
- package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
- package/dist/browser/modules/formula/runtime/values.js +385 -0
- package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/browser/modules/formula/syntax/ast.js +28 -0
- package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/browser/modules/formula/syntax/parser.js +439 -0
- package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/browser/modules/formula/syntax/token-types.js +59 -0
- package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/browser/modules/pdf/excel-bridge.js +9 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/modules/excel/cell.js +170 -22
- package/dist/cjs/modules/excel/defined-names.js +411 -21
- package/dist/cjs/modules/excel/image.js +24 -1
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/cjs/modules/excel/table.js +15 -2
- package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
- package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
- package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
- package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
- package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
- package/dist/cjs/modules/excel/workbook.browser.js +318 -34
- package/dist/cjs/modules/excel/worksheet.js +20 -1
- package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
- package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
- package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
- package/dist/cjs/modules/formula/compile/binder.js +489 -0
- package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
- package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
- package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
- package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
- package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
- package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
- package/dist/cjs/modules/formula/functions/_shared.js +396 -0
- package/dist/cjs/modules/formula/functions/conditional.js +354 -0
- package/dist/cjs/modules/formula/functions/database.js +288 -0
- package/dist/cjs/modules/formula/functions/date.js +883 -0
- package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
- package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
- package/dist/cjs/modules/formula/functions/financial.js +2348 -0
- package/dist/cjs/modules/formula/functions/lookup.js +902 -0
- package/dist/cjs/modules/formula/functions/math.js +1487 -0
- package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
- package/dist/cjs/modules/formula/functions/text.js +1889 -0
- package/dist/cjs/modules/formula/host-registry.js +75 -0
- package/dist/cjs/modules/formula/index.js +58 -0
- package/dist/cjs/modules/formula/install.js +93 -0
- package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
- package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
- package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
- package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
- package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
- package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
- package/dist/cjs/modules/formula/materialize/types.js +32 -0
- package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
- package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
- package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
- package/dist/cjs/modules/formula/runtime/values.js +385 -0
- package/dist/cjs/modules/formula/syntax/ast.js +8 -0
- package/dist/cjs/modules/formula/syntax/parser.js +440 -0
- package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
- package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
- package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
- package/dist/esm/index.browser.js +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/modules/excel/cell.js +170 -22
- package/dist/esm/modules/excel/defined-names.js +411 -21
- package/dist/esm/modules/excel/image.js +24 -1
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/esm/modules/excel/table.js +15 -2
- package/dist/esm/modules/excel/utils/col-cache.js +15 -0
- package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
- package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/esm/modules/excel/workbook.browser.js +318 -34
- package/dist/esm/modules/excel/worksheet.js +21 -2
- package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/esm/modules/formula/compile/address-utils.js +83 -0
- package/dist/esm/modules/formula/compile/binder.js +487 -0
- package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
- package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
- package/dist/esm/modules/formula/functions/_date-context.js +29 -0
- package/dist/esm/modules/formula/functions/_shared.js +381 -0
- package/dist/esm/modules/formula/functions/conditional.js +343 -0
- package/dist/esm/modules/formula/functions/database.js +274 -0
- package/dist/esm/modules/formula/functions/date.js +855 -0
- package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/esm/modules/formula/functions/engineering.js +1128 -0
- package/dist/esm/modules/formula/functions/financial.js +2296 -0
- package/dist/esm/modules/formula/functions/lookup.js +886 -0
- package/dist/esm/modules/formula/functions/math.js +1406 -0
- package/dist/esm/modules/formula/functions/statistical.js +3390 -0
- package/dist/esm/modules/formula/functions/text.js +1845 -0
- package/dist/esm/modules/formula/host-registry.js +69 -0
- package/dist/esm/modules/formula/index.js +49 -0
- package/dist/esm/modules/formula/install.js +88 -0
- package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
- package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/esm/modules/formula/materialize/types.js +29 -0
- package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
- package/dist/esm/modules/formula/runtime/values.js +385 -0
- package/dist/esm/modules/formula/syntax/ast.js +28 -0
- package/dist/esm/modules/formula/syntax/parser.js +439 -0
- package/dist/esm/modules/formula/syntax/token-types.js +59 -0
- package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/esm/modules/pdf/excel-bridge.js +9 -0
- package/dist/iife/excelts.iife.js +2302 -373
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +34 -34
- package/dist/types/index.browser.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/modules/excel/cell.d.ts +17 -3
- package/dist/types/modules/excel/defined-names.d.ts +96 -1
- package/dist/types/modules/excel/image.d.ts +11 -0
- package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/types/modules/excel/types.d.ts +133 -2
- package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/types/modules/excel/workbook.d.ts +1 -1
- package/dist/types/modules/excel/worksheet.d.ts +3 -1
- package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/types/modules/formula/compile/binder.d.ts +42 -0
- package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/types/modules/formula/functions/database.d.ts +37 -0
- package/dist/types/modules/formula/functions/date.d.ts +61 -0
- package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/types/modules/formula/functions/financial.d.ts +202 -0
- package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/types/modules/formula/functions/math.d.ts +114 -0
- package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/types/modules/formula/functions/text.d.ts +86 -0
- package/dist/types/modules/formula/host-registry.d.ts +53 -0
- package/dist/types/modules/formula/index.d.ts +39 -0
- package/dist/types/modules/formula/install.d.ts +62 -0
- package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/types/modules/formula/materialize/types.d.ts +179 -0
- package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/types/modules/formula/runtime/values.d.ts +211 -0
- package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/package.json +28 -28
|
@@ -0,0 +1,1183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Engineering Functions — Native RuntimeValue implementation.
|
|
4
|
+
*/
|
|
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.fnDEC2OCT = exports.fnOCT2DEC = exports.fnDEC2HEX = exports.fnHEX2DEC = exports.fnDEC2BIN = exports.fnBIN2DEC = void 0;
|
|
7
|
+
exports.fnBITRSHIFT = void 0;
|
|
8
|
+
const values_1 = require("../runtime/values");
|
|
9
|
+
const _shared_1 = require("./_shared");
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Base Conversion Functions
|
|
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
|
+
};
|
|
28
|
+
exports.fnBIN2DEC = fnBIN2DEC;
|
|
29
|
+
const fnDEC2BIN = args => {
|
|
30
|
+
const nRV = (0, values_1.toNumberRV)(args[0]);
|
|
31
|
+
if ((0, values_1.isError)(nRV)) {
|
|
32
|
+
return nRV;
|
|
33
|
+
}
|
|
34
|
+
// Excel's DEC→BASE family truncates toward zero, so negative fractions
|
|
35
|
+
// become `0`, not `-1` as `Math.floor` would produce.
|
|
36
|
+
const n = Math.trunc(nRV.value);
|
|
37
|
+
if (n < -512 || n > 511) {
|
|
38
|
+
return values_1.ERRORS.NUM;
|
|
39
|
+
}
|
|
40
|
+
// `places` is only meaningful when supplied and the input is non-negative.
|
|
41
|
+
// Excel restricts it to the [1, 10] range and returns #NUM! otherwise.
|
|
42
|
+
// For negative inputs Excel ignores `places` entirely, so we validate it
|
|
43
|
+
// only on the non-negative branch below.
|
|
44
|
+
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);
|
|
46
|
+
if ((0, values_1.isError)(placesRV)) {
|
|
47
|
+
return placesRV;
|
|
48
|
+
}
|
|
49
|
+
const places = Math.trunc(placesRV.value);
|
|
50
|
+
if (n < 0) {
|
|
51
|
+
return (0, values_1.rvString)((n + 1024).toString(2));
|
|
52
|
+
}
|
|
53
|
+
if (hasPlaces && (places < 1 || places > 10)) {
|
|
54
|
+
return values_1.ERRORS.NUM;
|
|
55
|
+
}
|
|
56
|
+
const result = n.toString(2);
|
|
57
|
+
return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
|
|
58
|
+
};
|
|
59
|
+
exports.fnDEC2BIN = fnDEC2BIN;
|
|
60
|
+
const fnHEX2DEC = args => {
|
|
61
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
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)) {
|
|
67
|
+
return values_1.ERRORS.NUM;
|
|
68
|
+
}
|
|
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
|
+
return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
|
|
109
|
+
};
|
|
110
|
+
exports.fnDEC2HEX = fnDEC2HEX;
|
|
111
|
+
const fnOCT2DEC = args => {
|
|
112
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
113
|
+
if (err) {
|
|
114
|
+
return err;
|
|
115
|
+
}
|
|
116
|
+
const s = (0, values_1.toStringRV)(args[0]);
|
|
117
|
+
if (!/^[0-7]{1,10}$/.test(s)) {
|
|
118
|
+
return values_1.ERRORS.NUM;
|
|
119
|
+
}
|
|
120
|
+
const num = parseInt(s, 8);
|
|
121
|
+
if (s.length === 10 && parseInt(s[0]) >= 4) {
|
|
122
|
+
return (0, values_1.rvNumber)(num - Math.pow(8, 10));
|
|
123
|
+
}
|
|
124
|
+
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;
|
|
160
|
+
/**
|
|
161
|
+
* Generic helper for the X2Y conversion family (BIN2HEX, HEX2BIN, …).
|
|
162
|
+
*
|
|
163
|
+
* `parseNInput` extracts the signed decimal value of the input string in
|
|
164
|
+
* its source base, enforcing the Excel length / digit-alphabet rules.
|
|
165
|
+
* `formatN` serialises the decimal back in the target base, honouring
|
|
166
|
+
* the optional `places` argument and the 10-digit two's-complement
|
|
167
|
+
* convention for negatives. Returning an `ErrorValue` from either stage
|
|
168
|
+
* aborts with that error — keeps each pairwise converter a three-liner.
|
|
169
|
+
*/
|
|
170
|
+
function convertBase(args, parseNInput, format) {
|
|
171
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
172
|
+
if (err) {
|
|
173
|
+
return err;
|
|
174
|
+
}
|
|
175
|
+
const s = (0, values_1.toStringRV)(args[0]);
|
|
176
|
+
const n = parseNInput(s);
|
|
177
|
+
if (typeof n !== "number") {
|
|
178
|
+
return n;
|
|
179
|
+
}
|
|
180
|
+
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);
|
|
182
|
+
if ((0, values_1.isError)(placesRV)) {
|
|
183
|
+
return placesRV;
|
|
184
|
+
}
|
|
185
|
+
const places = Math.trunc(placesRV.value);
|
|
186
|
+
return format(n, places, hasPlaces);
|
|
187
|
+
}
|
|
188
|
+
/** Parse a binary input string as a signed decimal, or return #NUM!. */
|
|
189
|
+
function parseBinInput(s) {
|
|
190
|
+
if (!/^[01]{1,10}$/.test(s)) {
|
|
191
|
+
return values_1.ERRORS.NUM;
|
|
192
|
+
}
|
|
193
|
+
const num = parseInt(s, 2);
|
|
194
|
+
return s.length === 10 && s[0] === "1" ? num - Math.pow(2, 10) : num;
|
|
195
|
+
}
|
|
196
|
+
function parseOctInput(s) {
|
|
197
|
+
if (!/^[0-7]{1,10}$/.test(s)) {
|
|
198
|
+
return values_1.ERRORS.NUM;
|
|
199
|
+
}
|
|
200
|
+
const num = parseInt(s, 8);
|
|
201
|
+
return s.length === 10 && parseInt(s[0]) >= 4 ? num - Math.pow(8, 10) : num;
|
|
202
|
+
}
|
|
203
|
+
function parseHexInput(s) {
|
|
204
|
+
if (!/^[0-9A-Fa-f]{1,10}$/.test(s)) {
|
|
205
|
+
return values_1.ERRORS.NUM;
|
|
206
|
+
}
|
|
207
|
+
const num = parseInt(s, 16);
|
|
208
|
+
return s.length === 10 && parseInt(s[0], 16) >= 8 ? num - Math.pow(16, 10) : num;
|
|
209
|
+
}
|
|
210
|
+
/** Format a signed decimal to the target base; handles 10-digit negatives. */
|
|
211
|
+
function formatToBase(n, base, maxDigits, places, hasPlaces) {
|
|
212
|
+
if (n < 0) {
|
|
213
|
+
// Two's-complement style: Excel emits the full 10-digit width.
|
|
214
|
+
return (0, values_1.rvString)((n + Math.pow(base, 10)).toString(base).toUpperCase());
|
|
215
|
+
}
|
|
216
|
+
if (hasPlaces && (places < 1 || places > maxDigits)) {
|
|
217
|
+
return values_1.ERRORS.NUM;
|
|
218
|
+
}
|
|
219
|
+
const result = n.toString(base).toUpperCase();
|
|
220
|
+
return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
|
|
221
|
+
}
|
|
222
|
+
const fnBIN2HEX = args => convertBase(args, parseBinInput, (n, places, hasPlaces) => formatToBase(n, 16, 10, places, hasPlaces));
|
|
223
|
+
exports.fnBIN2HEX = fnBIN2HEX;
|
|
224
|
+
const fnBIN2OCT = args => convertBase(args, parseBinInput, (n, places, hasPlaces) => formatToBase(n, 8, 10, places, hasPlaces));
|
|
225
|
+
exports.fnBIN2OCT = fnBIN2OCT;
|
|
226
|
+
const fnHEX2BIN = args => convertBase(args, parseHexInput, (n, places, hasPlaces) => {
|
|
227
|
+
// BIN can only hold values in [-512, 511]; Excel rejects anything wider.
|
|
228
|
+
if (n < -512 || n > 511) {
|
|
229
|
+
return values_1.ERRORS.NUM;
|
|
230
|
+
}
|
|
231
|
+
return formatToBase(n, 2, 10, places, hasPlaces);
|
|
232
|
+
});
|
|
233
|
+
exports.fnHEX2BIN = fnHEX2BIN;
|
|
234
|
+
const fnHEX2OCT = args => convertBase(args, parseHexInput, (n, places, hasPlaces) => {
|
|
235
|
+
// OCT holds values in [-2^29, 2^29 − 1].
|
|
236
|
+
if (n < -536870912 || n > 536870911) {
|
|
237
|
+
return values_1.ERRORS.NUM;
|
|
238
|
+
}
|
|
239
|
+
return formatToBase(n, 8, 10, places, hasPlaces);
|
|
240
|
+
});
|
|
241
|
+
exports.fnHEX2OCT = fnHEX2OCT;
|
|
242
|
+
const fnOCT2BIN = args => convertBase(args, parseOctInput, (n, places, hasPlaces) => {
|
|
243
|
+
if (n < -512 || n > 511) {
|
|
244
|
+
return values_1.ERRORS.NUM;
|
|
245
|
+
}
|
|
246
|
+
return formatToBase(n, 2, 10, places, hasPlaces);
|
|
247
|
+
});
|
|
248
|
+
exports.fnOCT2BIN = fnOCT2BIN;
|
|
249
|
+
const fnOCT2HEX = args => convertBase(args, parseOctInput, (n, places, hasPlaces) => formatToBase(n, 16, 10, places, hasPlaces));
|
|
250
|
+
exports.fnOCT2HEX = fnOCT2HEX;
|
|
251
|
+
// ============================================================================
|
|
252
|
+
// Bessel functions
|
|
253
|
+
// ============================================================================
|
|
254
|
+
//
|
|
255
|
+
// The four Bessel variants (J, I, K, Y) satisfy recurrences that make a
|
|
256
|
+
// rolling evaluation both simple and numerically stable for modest
|
|
257
|
+
// arguments. Excel restricts these to integer order n >= 0 and real
|
|
258
|
+
// x >= 0; we enforce those bounds and otherwise match the standard
|
|
259
|
+
// power-series / backward-recurrence algorithms used across numerical
|
|
260
|
+
// libraries. Accuracy is better than ~1e-6 relative for |x| <= 30 and n
|
|
261
|
+
// <= 30 — the realistic domain where anyone actually uses BESSEL in a
|
|
262
|
+
// spreadsheet.
|
|
263
|
+
function besselJ(n, x) {
|
|
264
|
+
// Series expansion for moderate x, Miller's backward recurrence for
|
|
265
|
+
// larger x. Switch point chosen empirically where the direct series
|
|
266
|
+
// begins to lose precision.
|
|
267
|
+
if (x === 0) {
|
|
268
|
+
return n === 0 ? 1 : 0;
|
|
269
|
+
}
|
|
270
|
+
const ax = Math.abs(x);
|
|
271
|
+
if (ax < 15) {
|
|
272
|
+
// Direct power series: Jₙ(x) = Σ (-1)^k (x/2)^(n+2k) / (k! (n+k)!)
|
|
273
|
+
const half = x / 2;
|
|
274
|
+
let term = Math.pow(half, n);
|
|
275
|
+
for (let k = 1; k <= n; k++) {
|
|
276
|
+
term /= k;
|
|
277
|
+
}
|
|
278
|
+
let sum = term;
|
|
279
|
+
for (let k = 1; k < 100; k++) {
|
|
280
|
+
term = (-term * half * half) / (k * (n + k));
|
|
281
|
+
sum += term;
|
|
282
|
+
if (Math.abs(term) < 1e-15 * Math.abs(sum)) {
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return sum;
|
|
287
|
+
}
|
|
288
|
+
// Backward recurrence (Miller's algorithm). Start from a high order,
|
|
289
|
+
// iterate down, normalise using the known sum ∑(−1)ᵏJ₂ₖ = 1.
|
|
290
|
+
//
|
|
291
|
+
// The starting order needs to be (a) even, (b) higher than `n`, and
|
|
292
|
+
// (c) large enough that the recurrence has converged. The classic
|
|
293
|
+
// `2 * (n + ceil(sqrt(40 * n)))` formula collapses to 0 when `n = 0`,
|
|
294
|
+
// which makes the loop never execute and leaves `ans = 0` (wrong —
|
|
295
|
+
// J₀(20) ≈ 0.167, not 0). Floor the start at `2*ceil(x + 20)` so
|
|
296
|
+
// small-`n` large-`x` inputs still get a meaningful number of
|
|
297
|
+
// recurrence steps.
|
|
298
|
+
const startRaw = 2 * (n + Math.ceil(Math.sqrt(40 * Math.max(n, 1))));
|
|
299
|
+
const startMin = 2 * Math.ceil(x + 20);
|
|
300
|
+
let start = Math.max(startRaw, startMin);
|
|
301
|
+
// Make sure start is even so the Σ(-1)^k J_{2k} = 1 identity applies
|
|
302
|
+
// cleanly during the loop below.
|
|
303
|
+
if (start % 2 !== 0) {
|
|
304
|
+
start++;
|
|
305
|
+
}
|
|
306
|
+
let bjp = 0;
|
|
307
|
+
let bj = 1;
|
|
308
|
+
let ans = 0;
|
|
309
|
+
let sum = 0;
|
|
310
|
+
for (let j = start; j > 0; j--) {
|
|
311
|
+
const bjm = (2 * j * bj) / x - bjp;
|
|
312
|
+
bjp = bj;
|
|
313
|
+
bj = bjm;
|
|
314
|
+
if (Math.abs(bj) > 1e10) {
|
|
315
|
+
bj *= 1e-10;
|
|
316
|
+
bjp *= 1e-10;
|
|
317
|
+
ans *= 1e-10;
|
|
318
|
+
sum *= 1e-10;
|
|
319
|
+
}
|
|
320
|
+
if (j % 2 === 0) {
|
|
321
|
+
sum += bj;
|
|
322
|
+
}
|
|
323
|
+
if (j === n) {
|
|
324
|
+
ans = bjp;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
sum = 2 * sum - bj;
|
|
328
|
+
return ans / sum;
|
|
329
|
+
}
|
|
330
|
+
function besselI(n, x) {
|
|
331
|
+
if (x === 0) {
|
|
332
|
+
return n === 0 ? 1 : 0;
|
|
333
|
+
}
|
|
334
|
+
// Iₙ(x) = Σ (x/2)^(n+2k) / (k! (n+k)!)
|
|
335
|
+
const half = x / 2;
|
|
336
|
+
let term = Math.pow(half, n);
|
|
337
|
+
for (let k = 1; k <= n; k++) {
|
|
338
|
+
term /= k;
|
|
339
|
+
}
|
|
340
|
+
let sum = term;
|
|
341
|
+
for (let k = 1; k < 200; k++) {
|
|
342
|
+
term = (term * half * half) / (k * (n + k));
|
|
343
|
+
sum += term;
|
|
344
|
+
if (Math.abs(term) < 1e-15 * Math.abs(sum)) {
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return sum;
|
|
349
|
+
}
|
|
350
|
+
function besselY(n, x) {
|
|
351
|
+
// Y₀ / Y₁ via standard small-argument expansions; higher orders via
|
|
352
|
+
// forward recurrence. Accuracy is modest (~1e-5) but matches Excel's
|
|
353
|
+
// own precision for BESSELY.
|
|
354
|
+
if (x === 0) {
|
|
355
|
+
return Number.NEGATIVE_INFINITY;
|
|
356
|
+
}
|
|
357
|
+
const y0 = (xv) => {
|
|
358
|
+
if (xv < 8) {
|
|
359
|
+
const y = xv * xv;
|
|
360
|
+
const ans1 = -2957821389 +
|
|
361
|
+
y *
|
|
362
|
+
(7062834065 +
|
|
363
|
+
y * (-512359803.6 + y * (10879881.29 + y * (-86327.92757 + y * 228.4622733))));
|
|
364
|
+
const ans2 = 40076544269 +
|
|
365
|
+
y * (745249964.8 + y * (7189466.438 + y * (47447.2647 + y * (226.1030244 + y))));
|
|
366
|
+
return ans1 / ans2 + 0.636619772 * besselJ(0, xv) * Math.log(xv);
|
|
367
|
+
}
|
|
368
|
+
const z = 8 / xv;
|
|
369
|
+
const y = z * z;
|
|
370
|
+
const ans1 = 1 +
|
|
371
|
+
y * (-0.1098628627e-2 + y * (0.2734510407e-4 + y * (-0.2073370639e-5 + y * 0.2093887211e-6)));
|
|
372
|
+
const ans2 = -0.1562499995e-1 +
|
|
373
|
+
y * (0.1430488765e-3 + y * (-0.6911147651e-5 + y * (0.7621095161e-6 + y * -0.934945152e-7)));
|
|
374
|
+
return (Math.sqrt(0.636619772 / xv) *
|
|
375
|
+
(Math.sin(xv - 0.785398164) * ans1 + z * Math.cos(xv - 0.785398164) * ans2));
|
|
376
|
+
};
|
|
377
|
+
const y1 = (xv) => {
|
|
378
|
+
if (xv < 8) {
|
|
379
|
+
const y = xv * xv;
|
|
380
|
+
const ans1 = xv *
|
|
381
|
+
(-0.4900604943e13 +
|
|
382
|
+
y *
|
|
383
|
+
(0.127527439e13 +
|
|
384
|
+
y *
|
|
385
|
+
(-0.5153438139e11 +
|
|
386
|
+
y * (0.7349264551e9 + y * (-0.4237922726e7 + y * 0.8511937935e4)))));
|
|
387
|
+
const ans2 = 0.249958057e14 +
|
|
388
|
+
y *
|
|
389
|
+
(0.4244419664e12 +
|
|
390
|
+
y *
|
|
391
|
+
(0.3733650367e10 +
|
|
392
|
+
y * (0.2245904002e8 + y * (0.102042605e6 + y * (0.3549632885e3 + y)))));
|
|
393
|
+
return ans1 / ans2 + 0.636619772 * (besselJ(1, xv) * Math.log(xv) - 1 / xv);
|
|
394
|
+
}
|
|
395
|
+
const z = 8 / xv;
|
|
396
|
+
const y = z * z;
|
|
397
|
+
const ans1 = 1 + y * (0.183105e-2 + y * (-0.3516396496e-4 + y * (0.2457520174e-5 + y * -0.240337019e-6)));
|
|
398
|
+
const ans2 = 0.04687499995 +
|
|
399
|
+
y * (-0.2002690873e-3 + y * (0.8449199096e-5 + y * (-0.88228987e-6 + y * 0.105787412e-6)));
|
|
400
|
+
return (Math.sqrt(0.636619772 / xv) *
|
|
401
|
+
(Math.sin(xv - 2.356194491) * ans1 + z * Math.cos(xv - 2.356194491) * ans2));
|
|
402
|
+
};
|
|
403
|
+
if (n === 0) {
|
|
404
|
+
return y0(x);
|
|
405
|
+
}
|
|
406
|
+
if (n === 1) {
|
|
407
|
+
return y1(x);
|
|
408
|
+
}
|
|
409
|
+
let bym = y0(x);
|
|
410
|
+
let by = y1(x);
|
|
411
|
+
for (let j = 1; j < n; j++) {
|
|
412
|
+
const byp = (2 * j * by) / x - bym;
|
|
413
|
+
bym = by;
|
|
414
|
+
by = byp;
|
|
415
|
+
}
|
|
416
|
+
return by;
|
|
417
|
+
}
|
|
418
|
+
function besselK(n, x) {
|
|
419
|
+
if (x === 0) {
|
|
420
|
+
return Number.POSITIVE_INFINITY;
|
|
421
|
+
}
|
|
422
|
+
const k0 = (xv) => {
|
|
423
|
+
if (xv <= 2) {
|
|
424
|
+
const y = (xv * xv) / 4;
|
|
425
|
+
return (-Math.log(xv / 2) * besselI(0, xv) +
|
|
426
|
+
(-0.57721566 +
|
|
427
|
+
y *
|
|
428
|
+
(0.4227842 +
|
|
429
|
+
y *
|
|
430
|
+
(0.23069756 +
|
|
431
|
+
y * (0.0348859 + y * (0.00262698 + y * (0.0001075 + y * 0.0000074)))))));
|
|
432
|
+
}
|
|
433
|
+
const y = 2 / xv;
|
|
434
|
+
return ((Math.exp(-xv) / Math.sqrt(xv)) *
|
|
435
|
+
(1.25331414 +
|
|
436
|
+
y *
|
|
437
|
+
(-0.07832358 +
|
|
438
|
+
y *
|
|
439
|
+
(0.02189568 +
|
|
440
|
+
y * (-0.01062446 + y * (0.00587872 + y * (-0.0025154 + y * 0.00053208)))))));
|
|
441
|
+
};
|
|
442
|
+
const k1 = (xv) => {
|
|
443
|
+
if (xv <= 2) {
|
|
444
|
+
const y = (xv * xv) / 4;
|
|
445
|
+
return (Math.log(xv / 2) * besselI(1, xv) +
|
|
446
|
+
(1 / xv) *
|
|
447
|
+
(1 +
|
|
448
|
+
y *
|
|
449
|
+
(0.15443144 +
|
|
450
|
+
y *
|
|
451
|
+
(-0.67278579 +
|
|
452
|
+
y * (-0.18156897 + y * (-0.01919402 + y * (-0.00110404 + y * -0.00004686)))))));
|
|
453
|
+
}
|
|
454
|
+
const y = 2 / xv;
|
|
455
|
+
return ((Math.exp(-xv) / Math.sqrt(xv)) *
|
|
456
|
+
(1.25331414 +
|
|
457
|
+
y *
|
|
458
|
+
(0.23498619 +
|
|
459
|
+
y *
|
|
460
|
+
(-0.0365562 +
|
|
461
|
+
y * (0.01504268 + y * (-0.00780353 + y * (0.00325614 + y * -0.00068245)))))));
|
|
462
|
+
};
|
|
463
|
+
if (n === 0) {
|
|
464
|
+
return k0(x);
|
|
465
|
+
}
|
|
466
|
+
if (n === 1) {
|
|
467
|
+
return k1(x);
|
|
468
|
+
}
|
|
469
|
+
// Kₙ₊₁(x) = (2n/x) Kₙ(x) + Kₙ₋₁(x)
|
|
470
|
+
let bkm = k0(x);
|
|
471
|
+
let bk = k1(x);
|
|
472
|
+
for (let j = 1; j < n; j++) {
|
|
473
|
+
const bkp = (2 * j * bk) / x + bkm;
|
|
474
|
+
bkm = bk;
|
|
475
|
+
bk = bkp;
|
|
476
|
+
}
|
|
477
|
+
return bk;
|
|
478
|
+
}
|
|
479
|
+
/** Common validation + dispatch for the four BESSEL* functions. */
|
|
480
|
+
function bessel(args, compute, allowZeroX) {
|
|
481
|
+
const xRV = (0, values_1.toNumberRV)(args[0]);
|
|
482
|
+
if ((0, values_1.isError)(xRV)) {
|
|
483
|
+
return xRV;
|
|
484
|
+
}
|
|
485
|
+
const nRV = (0, values_1.toNumberRV)(args[1]);
|
|
486
|
+
if ((0, values_1.isError)(nRV)) {
|
|
487
|
+
return nRV;
|
|
488
|
+
}
|
|
489
|
+
const n = Math.trunc(nRV.value);
|
|
490
|
+
// Excel accepts any real x for BESSELJ / BESSELI but requires x > 0
|
|
491
|
+
// for BESSELK / BESSELY (the log-term blows up at zero). For all four
|
|
492
|
+
// the order n must be a non-negative integer.
|
|
493
|
+
if (n < 0) {
|
|
494
|
+
return values_1.ERRORS.NUM;
|
|
495
|
+
}
|
|
496
|
+
if (!allowZeroX && xRV.value <= 0) {
|
|
497
|
+
return values_1.ERRORS.NUM;
|
|
498
|
+
}
|
|
499
|
+
if (allowZeroX && xRV.value < 0) {
|
|
500
|
+
return values_1.ERRORS.NUM;
|
|
501
|
+
}
|
|
502
|
+
const result = compute(n, xRV.value);
|
|
503
|
+
return Number.isFinite(result) ? (0, values_1.rvNumber)(result) : values_1.ERRORS.NUM;
|
|
504
|
+
}
|
|
505
|
+
const fnBESSELJ = args => bessel(args, besselJ, true);
|
|
506
|
+
exports.fnBESSELJ = fnBESSELJ;
|
|
507
|
+
const fnBESSELI = args => bessel(args, besselI, true);
|
|
508
|
+
exports.fnBESSELI = fnBESSELI;
|
|
509
|
+
const fnBESSELK = args => bessel(args, besselK, false);
|
|
510
|
+
exports.fnBESSELK = fnBESSELK;
|
|
511
|
+
const fnBESSELY = args => bessel(args, besselY, false);
|
|
512
|
+
exports.fnBESSELY = fnBESSELY;
|
|
513
|
+
const fnDELTA = args => {
|
|
514
|
+
const n1 = (0, values_1.toNumberRV)(args[0]);
|
|
515
|
+
if ((0, values_1.isError)(n1)) {
|
|
516
|
+
return n1;
|
|
517
|
+
}
|
|
518
|
+
const n2 = args.length > 1 ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
519
|
+
if ((0, values_1.isError)(n2)) {
|
|
520
|
+
return n2;
|
|
521
|
+
}
|
|
522
|
+
return (0, values_1.rvNumber)(n1.value === n2.value ? 1 : 0);
|
|
523
|
+
};
|
|
524
|
+
exports.fnDELTA = fnDELTA;
|
|
525
|
+
const fnGESTEP = args => {
|
|
526
|
+
const n = (0, values_1.toNumberRV)(args[0]);
|
|
527
|
+
if ((0, values_1.isError)(n)) {
|
|
528
|
+
return n;
|
|
529
|
+
}
|
|
530
|
+
const step = args.length > 1 ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
531
|
+
if ((0, values_1.isError)(step)) {
|
|
532
|
+
return step;
|
|
533
|
+
}
|
|
534
|
+
return (0, values_1.rvNumber)(n.value >= step.value ? 1 : 0);
|
|
535
|
+
};
|
|
536
|
+
exports.fnGESTEP = fnGESTEP;
|
|
537
|
+
// ============================================================================
|
|
538
|
+
// Complex Numbers, Bit Operations
|
|
539
|
+
// ============================================================================
|
|
540
|
+
function parseComplex(s) {
|
|
541
|
+
const text = s.trim();
|
|
542
|
+
if (text === "") {
|
|
543
|
+
return null;
|
|
544
|
+
}
|
|
545
|
+
// A valid numeric component (real or imaginary coefficient) must match
|
|
546
|
+
// this strict decimal grammar. Without it, the permissive fallback
|
|
547
|
+
// regex below lets garbage like "1.2.3+4i" or "ee+i" match and we
|
|
548
|
+
// then coerced NaN to 0, silently returning bogus complex numbers for
|
|
549
|
+
// 19 downstream IM* call sites. See R6-P0-2.
|
|
550
|
+
const NUM_RE = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
551
|
+
const toNumStrict = (x) => (NUM_RE.test(x) ? Number(x) : Number.NaN);
|
|
552
|
+
const pureReal = toNumStrict(text);
|
|
553
|
+
if (!Number.isNaN(pureReal) && !text.endsWith("i") && !text.endsWith("j")) {
|
|
554
|
+
return [pureReal, 0];
|
|
555
|
+
}
|
|
556
|
+
if (text === "i" || text === "j") {
|
|
557
|
+
return [0, 1];
|
|
558
|
+
}
|
|
559
|
+
if (text === "-i" || text === "-j") {
|
|
560
|
+
return [0, -1];
|
|
561
|
+
}
|
|
562
|
+
if (text === "+i" || text === "+j") {
|
|
563
|
+
return [0, 1];
|
|
564
|
+
}
|
|
565
|
+
// Pure imaginary "<num>i" or "<num>j"
|
|
566
|
+
if (text.endsWith("i") || text.endsWith("j")) {
|
|
567
|
+
const coef = text.slice(0, -1);
|
|
568
|
+
const coefNum = toNumStrict(coef);
|
|
569
|
+
if (!Number.isNaN(coefNum)) {
|
|
570
|
+
return [0, coefNum];
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
// Mixed real+imaginary form.
|
|
574
|
+
const re = /^([+-]?[\d.eE+-]*?)([+-][\d.eE]*)?[ij]$/;
|
|
575
|
+
const m = re.exec(text);
|
|
576
|
+
if (!m) {
|
|
577
|
+
return null;
|
|
578
|
+
}
|
|
579
|
+
const realRaw = m[1] ?? "";
|
|
580
|
+
const imagRaw = m[2] ?? "";
|
|
581
|
+
// Validate each component with the strict grammar (treating the bare
|
|
582
|
+
// sign tokens "+"/"-" as implicit coefficients of 1 / -1, matching
|
|
583
|
+
// Excel's "x+i" == "x+1i" shorthand).
|
|
584
|
+
const realPart = realRaw === "" || realRaw === "+" ? 0 : realRaw === "-" ? 0 : toNumStrict(realRaw);
|
|
585
|
+
const imagPart = imagRaw === "" ? 0 : imagRaw === "+" ? 1 : imagRaw === "-" ? -1 : toNumStrict(imagRaw);
|
|
586
|
+
if (Number.isNaN(realPart) || Number.isNaN(imagPart)) {
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
if (imagRaw === "" && realRaw !== "") {
|
|
590
|
+
// "5i" form already handled above; this branch would only fire
|
|
591
|
+
// for something like "+i" / "-i" which is caught earlier.
|
|
592
|
+
return null;
|
|
593
|
+
}
|
|
594
|
+
return [realPart, imagPart];
|
|
595
|
+
}
|
|
596
|
+
function formatComplex(re, im, suffix = "i") {
|
|
597
|
+
if (im === 0) {
|
|
598
|
+
return String(re);
|
|
599
|
+
}
|
|
600
|
+
if (re === 0) {
|
|
601
|
+
if (im === 1) {
|
|
602
|
+
return suffix;
|
|
603
|
+
}
|
|
604
|
+
if (im === -1) {
|
|
605
|
+
return "-" + suffix;
|
|
606
|
+
}
|
|
607
|
+
return im + suffix;
|
|
608
|
+
}
|
|
609
|
+
const imStr = im === 1 ? "+" + suffix : im === -1 ? "-" + suffix : (im > 0 ? "+" : "") + im + suffix;
|
|
610
|
+
return re + imStr;
|
|
611
|
+
}
|
|
612
|
+
const fnCOMPLEX = args => {
|
|
613
|
+
const re = (0, values_1.toNumberRV)(args[0]);
|
|
614
|
+
if ((0, values_1.isError)(re)) {
|
|
615
|
+
return re;
|
|
616
|
+
}
|
|
617
|
+
const im = (0, values_1.toNumberRV)(args[1]);
|
|
618
|
+
if ((0, values_1.isError)(im)) {
|
|
619
|
+
return im;
|
|
620
|
+
}
|
|
621
|
+
let suffix = "i";
|
|
622
|
+
if (args.length > 2) {
|
|
623
|
+
const e2 = (0, _shared_1.checkError)(args[2]);
|
|
624
|
+
if (e2) {
|
|
625
|
+
return e2;
|
|
626
|
+
}
|
|
627
|
+
suffix = (0, values_1.toStringRV)(args[2]);
|
|
628
|
+
}
|
|
629
|
+
if (suffix !== "i" && suffix !== "j") {
|
|
630
|
+
return values_1.ERRORS.VALUE;
|
|
631
|
+
}
|
|
632
|
+
return (0, values_1.rvString)(formatComplex(re.value, im.value, suffix));
|
|
633
|
+
};
|
|
634
|
+
exports.fnCOMPLEX = fnCOMPLEX;
|
|
635
|
+
const fnIMREAL = args => {
|
|
636
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
637
|
+
if (err) {
|
|
638
|
+
return err;
|
|
639
|
+
}
|
|
640
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
641
|
+
return c ? (0, values_1.rvNumber)(c[0]) : values_1.ERRORS.NUM;
|
|
642
|
+
};
|
|
643
|
+
exports.fnIMREAL = fnIMREAL;
|
|
644
|
+
const fnIMAGINARY = args => {
|
|
645
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
646
|
+
if (err) {
|
|
647
|
+
return err;
|
|
648
|
+
}
|
|
649
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
650
|
+
return c ? (0, values_1.rvNumber)(c[1]) : values_1.ERRORS.NUM;
|
|
651
|
+
};
|
|
652
|
+
exports.fnIMAGINARY = fnIMAGINARY;
|
|
653
|
+
const fnIMABS = args => {
|
|
654
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
655
|
+
if (err) {
|
|
656
|
+
return err;
|
|
657
|
+
}
|
|
658
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
659
|
+
if (!c) {
|
|
660
|
+
return values_1.ERRORS.NUM;
|
|
661
|
+
}
|
|
662
|
+
return (0, values_1.rvNumber)(Math.sqrt(c[0] * c[0] + c[1] * c[1]));
|
|
663
|
+
};
|
|
664
|
+
exports.fnIMABS = fnIMABS;
|
|
665
|
+
const fnIMARGUMENT = args => {
|
|
666
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
667
|
+
if (err) {
|
|
668
|
+
return err;
|
|
669
|
+
}
|
|
670
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
671
|
+
if (!c) {
|
|
672
|
+
return values_1.ERRORS.NUM;
|
|
673
|
+
}
|
|
674
|
+
if (c[0] === 0 && c[1] === 0) {
|
|
675
|
+
return values_1.ERRORS.DIV0;
|
|
676
|
+
}
|
|
677
|
+
return (0, values_1.rvNumber)(Math.atan2(c[1], c[0]));
|
|
678
|
+
};
|
|
679
|
+
exports.fnIMARGUMENT = fnIMARGUMENT;
|
|
680
|
+
const fnIMCONJUGATE = args => {
|
|
681
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
682
|
+
if (err) {
|
|
683
|
+
return err;
|
|
684
|
+
}
|
|
685
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
686
|
+
if (!c) {
|
|
687
|
+
return values_1.ERRORS.NUM;
|
|
688
|
+
}
|
|
689
|
+
return (0, values_1.rvString)(formatComplex(c[0], -c[1]));
|
|
690
|
+
};
|
|
691
|
+
exports.fnIMCONJUGATE = fnIMCONJUGATE;
|
|
692
|
+
/**
|
|
693
|
+
* Iterate every scalar cell in a complex-number argument, invoking `step`
|
|
694
|
+
* on the parsed `[re, im]` pair. Accepts arrays, ranges and single
|
|
695
|
+
* scalars; numbers are treated as real, errors propagate, blanks are
|
|
696
|
+
* skipped, non-parseable strings yield `#NUM!`.
|
|
697
|
+
*/
|
|
698
|
+
function forEachComplexCell(arg, step) {
|
|
699
|
+
const visit = (cell) => {
|
|
700
|
+
if (cell.kind === 4 /* RVKind.Error */) {
|
|
701
|
+
return cell;
|
|
702
|
+
}
|
|
703
|
+
if (cell.kind === 0 /* RVKind.Blank */) {
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
if (cell.kind === 1 /* RVKind.Number */) {
|
|
707
|
+
step(cell.value, 0);
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
if (cell.kind === 3 /* RVKind.Boolean */) {
|
|
711
|
+
step(cell.value ? 1 : 0, 0);
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
if (cell.kind === 2 /* RVKind.String */) {
|
|
715
|
+
const c = parseComplex(cell.value);
|
|
716
|
+
if (!c) {
|
|
717
|
+
return values_1.ERRORS.NUM;
|
|
718
|
+
}
|
|
719
|
+
step(c[0], c[1]);
|
|
720
|
+
return null;
|
|
721
|
+
}
|
|
722
|
+
return null;
|
|
723
|
+
};
|
|
724
|
+
if (arg.kind === 5 /* RVKind.Array */) {
|
|
725
|
+
for (const row of arg.rows) {
|
|
726
|
+
for (const cell of row) {
|
|
727
|
+
const err = visit(cell);
|
|
728
|
+
if (err) {
|
|
729
|
+
return err;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
// Non-array: visit the scalar directly (references have already been
|
|
736
|
+
// dereferenced to either an array or a scalar by the evaluator).
|
|
737
|
+
return visit(arg);
|
|
738
|
+
}
|
|
739
|
+
const fnIMSUM = args => {
|
|
740
|
+
let re = 0;
|
|
741
|
+
let im = 0;
|
|
742
|
+
for (const a of args) {
|
|
743
|
+
const err = (0, _shared_1.checkError)(a);
|
|
744
|
+
if (err) {
|
|
745
|
+
return err;
|
|
746
|
+
}
|
|
747
|
+
const walkErr = forEachComplexCell(a, (r, i) => {
|
|
748
|
+
re += r;
|
|
749
|
+
im += i;
|
|
750
|
+
});
|
|
751
|
+
if (walkErr) {
|
|
752
|
+
return walkErr;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
return (0, values_1.rvString)(formatComplex(re, im));
|
|
756
|
+
};
|
|
757
|
+
exports.fnIMSUM = fnIMSUM;
|
|
758
|
+
const fnIMSUB = args => {
|
|
759
|
+
const e0 = (0, _shared_1.checkError)(args[0]);
|
|
760
|
+
if (e0) {
|
|
761
|
+
return e0;
|
|
762
|
+
}
|
|
763
|
+
const e1 = (0, _shared_1.checkError)(args[1]);
|
|
764
|
+
if (e1) {
|
|
765
|
+
return e1;
|
|
766
|
+
}
|
|
767
|
+
const c1 = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
768
|
+
const c2 = parseComplex((0, values_1.toStringRV)(args[1]));
|
|
769
|
+
if (!c1 || !c2) {
|
|
770
|
+
return values_1.ERRORS.NUM;
|
|
771
|
+
}
|
|
772
|
+
return (0, values_1.rvString)(formatComplex(c1[0] - c2[0], c1[1] - c2[1]));
|
|
773
|
+
};
|
|
774
|
+
exports.fnIMSUB = fnIMSUB;
|
|
775
|
+
const fnIMPRODUCT = args => {
|
|
776
|
+
let re = 1;
|
|
777
|
+
let im = 0;
|
|
778
|
+
for (const a of args) {
|
|
779
|
+
const err = (0, _shared_1.checkError)(a);
|
|
780
|
+
if (err) {
|
|
781
|
+
return err;
|
|
782
|
+
}
|
|
783
|
+
const walkErr = forEachComplexCell(a, (r, i) => {
|
|
784
|
+
const nRe = re * r - im * i;
|
|
785
|
+
const nIm = re * i + im * r;
|
|
786
|
+
re = nRe;
|
|
787
|
+
im = nIm;
|
|
788
|
+
});
|
|
789
|
+
if (walkErr) {
|
|
790
|
+
return walkErr;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return (0, values_1.rvString)(formatComplex(re, im));
|
|
794
|
+
};
|
|
795
|
+
exports.fnIMPRODUCT = fnIMPRODUCT;
|
|
796
|
+
const fnIMDIV = args => {
|
|
797
|
+
const e0 = (0, _shared_1.checkError)(args[0]);
|
|
798
|
+
if (e0) {
|
|
799
|
+
return e0;
|
|
800
|
+
}
|
|
801
|
+
const e1 = (0, _shared_1.checkError)(args[1]);
|
|
802
|
+
if (e1) {
|
|
803
|
+
return e1;
|
|
804
|
+
}
|
|
805
|
+
const c1 = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
806
|
+
const c2 = parseComplex((0, values_1.toStringRV)(args[1]));
|
|
807
|
+
if (!c1 || !c2) {
|
|
808
|
+
return values_1.ERRORS.NUM;
|
|
809
|
+
}
|
|
810
|
+
const d = c2[0] * c2[0] + c2[1] * c2[1];
|
|
811
|
+
if (d === 0) {
|
|
812
|
+
// Division by 0+0i. Excel's IMDIV returns `#NUM!` historically but
|
|
813
|
+
// our newer `cdiv` helper (used by IMTAN/IMCSC/etc.) returns
|
|
814
|
+
// `#DIV/0!`. Route to `#DIV/0!` here for engine-wide consistency
|
|
815
|
+
// with how the rest of the complex family handles the same
|
|
816
|
+
// singularity.
|
|
817
|
+
return values_1.ERRORS.DIV0;
|
|
818
|
+
}
|
|
819
|
+
return (0, values_1.rvString)(formatComplex((c1[0] * c2[0] + c1[1] * c2[1]) / d, (c1[1] * c2[0] - c1[0] * c2[1]) / d));
|
|
820
|
+
};
|
|
821
|
+
exports.fnIMDIV = fnIMDIV;
|
|
822
|
+
const fnIMPOWER = args => {
|
|
823
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
824
|
+
if (err) {
|
|
825
|
+
return err;
|
|
826
|
+
}
|
|
827
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
828
|
+
if (!c) {
|
|
829
|
+
return values_1.ERRORS.NUM;
|
|
830
|
+
}
|
|
831
|
+
const n = (0, values_1.toNumberRV)(args[1]);
|
|
832
|
+
if ((0, values_1.isError)(n)) {
|
|
833
|
+
return n;
|
|
834
|
+
}
|
|
835
|
+
const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
|
|
836
|
+
const theta = Math.atan2(c[1], c[0]);
|
|
837
|
+
const rn = Math.pow(r, n.value);
|
|
838
|
+
return (0, values_1.rvString)(formatComplex(rn * Math.cos(n.value * theta), rn * Math.sin(n.value * theta)));
|
|
839
|
+
};
|
|
840
|
+
exports.fnIMPOWER = fnIMPOWER;
|
|
841
|
+
const fnIMSQRT = args => {
|
|
842
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
843
|
+
if (err) {
|
|
844
|
+
return err;
|
|
845
|
+
}
|
|
846
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
847
|
+
if (!c) {
|
|
848
|
+
return values_1.ERRORS.NUM;
|
|
849
|
+
}
|
|
850
|
+
const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
|
|
851
|
+
const theta = Math.atan2(c[1], c[0]);
|
|
852
|
+
const sr = Math.sqrt(r);
|
|
853
|
+
return (0, values_1.rvString)(formatComplex(sr * Math.cos(theta / 2), sr * Math.sin(theta / 2)));
|
|
854
|
+
};
|
|
855
|
+
exports.fnIMSQRT = fnIMSQRT;
|
|
856
|
+
const fnIMLN = args => {
|
|
857
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
858
|
+
if (err) {
|
|
859
|
+
return err;
|
|
860
|
+
}
|
|
861
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
862
|
+
if (!c) {
|
|
863
|
+
return values_1.ERRORS.NUM;
|
|
864
|
+
}
|
|
865
|
+
const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
|
|
866
|
+
if (r === 0) {
|
|
867
|
+
return values_1.ERRORS.NUM;
|
|
868
|
+
}
|
|
869
|
+
return (0, values_1.rvString)(formatComplex(Math.log(r), Math.atan2(c[1], c[0])));
|
|
870
|
+
};
|
|
871
|
+
exports.fnIMLN = fnIMLN;
|
|
872
|
+
const fnIMLOG2 = args => {
|
|
873
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
874
|
+
if (err) {
|
|
875
|
+
return err;
|
|
876
|
+
}
|
|
877
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
878
|
+
if (!c) {
|
|
879
|
+
return values_1.ERRORS.NUM;
|
|
880
|
+
}
|
|
881
|
+
const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
|
|
882
|
+
if (r === 0) {
|
|
883
|
+
return values_1.ERRORS.NUM;
|
|
884
|
+
}
|
|
885
|
+
const ln2 = Math.log(2);
|
|
886
|
+
return (0, values_1.rvString)(formatComplex(Math.log(r) / ln2, Math.atan2(c[1], c[0]) / ln2));
|
|
887
|
+
};
|
|
888
|
+
exports.fnIMLOG2 = fnIMLOG2;
|
|
889
|
+
const fnIMLOG10 = args => {
|
|
890
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
891
|
+
if (err) {
|
|
892
|
+
return err;
|
|
893
|
+
}
|
|
894
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
895
|
+
if (!c) {
|
|
896
|
+
return values_1.ERRORS.NUM;
|
|
897
|
+
}
|
|
898
|
+
const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
|
|
899
|
+
if (r === 0) {
|
|
900
|
+
return values_1.ERRORS.NUM;
|
|
901
|
+
}
|
|
902
|
+
const ln10 = Math.log(10);
|
|
903
|
+
return (0, values_1.rvString)(formatComplex(Math.log(r) / ln10, Math.atan2(c[1], c[0]) / ln10));
|
|
904
|
+
};
|
|
905
|
+
exports.fnIMLOG10 = fnIMLOG10;
|
|
906
|
+
const fnIMEXP = args => {
|
|
907
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
908
|
+
if (err) {
|
|
909
|
+
return err;
|
|
910
|
+
}
|
|
911
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
912
|
+
if (!c) {
|
|
913
|
+
return values_1.ERRORS.NUM;
|
|
914
|
+
}
|
|
915
|
+
const er = Math.exp(c[0]);
|
|
916
|
+
return (0, values_1.rvString)(formatComplex(er * Math.cos(c[1]), er * Math.sin(c[1])));
|
|
917
|
+
};
|
|
918
|
+
exports.fnIMEXP = fnIMEXP;
|
|
919
|
+
const fnIMSIN = args => {
|
|
920
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
921
|
+
if (err) {
|
|
922
|
+
return err;
|
|
923
|
+
}
|
|
924
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
925
|
+
if (!c) {
|
|
926
|
+
return values_1.ERRORS.NUM;
|
|
927
|
+
}
|
|
928
|
+
return (0, values_1.rvString)(formatComplex(Math.sin(c[0]) * Math.cosh(c[1]), Math.cos(c[0]) * Math.sinh(c[1])));
|
|
929
|
+
};
|
|
930
|
+
exports.fnIMSIN = fnIMSIN;
|
|
931
|
+
const fnIMCOS = args => {
|
|
932
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
933
|
+
if (err) {
|
|
934
|
+
return err;
|
|
935
|
+
}
|
|
936
|
+
const c = parseComplex((0, values_1.toStringRV)(args[0]));
|
|
937
|
+
if (!c) {
|
|
938
|
+
return values_1.ERRORS.NUM;
|
|
939
|
+
}
|
|
940
|
+
return (0, values_1.rvString)(formatComplex(Math.cos(c[0]) * Math.cosh(c[1]), -Math.sin(c[0]) * Math.sinh(c[1])));
|
|
941
|
+
};
|
|
942
|
+
exports.fnIMCOS = fnIMCOS;
|
|
943
|
+
/**
|
|
944
|
+
* Shared helper: parse a single complex argument and either hand it to
|
|
945
|
+
* `compute` (which returns `[re, im]` or an error) or short-circuit the
|
|
946
|
+
* error. All the IM* functions added in R7 share this shape.
|
|
947
|
+
*/
|
|
948
|
+
function unaryComplex(args, compute) {
|
|
949
|
+
const err = (0, _shared_1.checkError)(args[0]);
|
|
950
|
+
if (err) {
|
|
951
|
+
return err;
|
|
952
|
+
}
|
|
953
|
+
// Allow number / boolean direct inputs: complex parser expects a
|
|
954
|
+
// string, but Excel's IM* family coerces booleans to 1/0 and numbers
|
|
955
|
+
// to pure-real complex. Falling through to `toStringRV` would render
|
|
956
|
+
// "TRUE" and then fail parsing.
|
|
957
|
+
const scalar = (0, values_1.topLeft)(args[0]);
|
|
958
|
+
let c;
|
|
959
|
+
if (scalar.kind === 1 /* RVKind.Number */) {
|
|
960
|
+
c = [scalar.value, 0];
|
|
961
|
+
}
|
|
962
|
+
else if (scalar.kind === 3 /* RVKind.Boolean */) {
|
|
963
|
+
c = [scalar.value ? 1 : 0, 0];
|
|
964
|
+
}
|
|
965
|
+
else if (scalar.kind === 0 /* RVKind.Blank */) {
|
|
966
|
+
c = [0, 0];
|
|
967
|
+
}
|
|
968
|
+
else {
|
|
969
|
+
c = parseComplex((0, values_1.toStringRV)(scalar));
|
|
970
|
+
}
|
|
971
|
+
if (!c) {
|
|
972
|
+
return values_1.ERRORS.NUM;
|
|
973
|
+
}
|
|
974
|
+
const result = compute(c[0], c[1]);
|
|
975
|
+
if ("kind" in result && result.kind === 4 /* RVKind.Error */) {
|
|
976
|
+
return result;
|
|
977
|
+
}
|
|
978
|
+
const [re, im] = result;
|
|
979
|
+
if (!Number.isFinite(re) || !Number.isFinite(im)) {
|
|
980
|
+
return values_1.ERRORS.NUM;
|
|
981
|
+
}
|
|
982
|
+
return (0, values_1.rvString)(formatComplex(re, im));
|
|
983
|
+
}
|
|
984
|
+
/** Divide two complex numbers (a / b). */
|
|
985
|
+
function cdiv(a, b) {
|
|
986
|
+
const denom = b[0] * b[0] + b[1] * b[1];
|
|
987
|
+
if (denom === 0) {
|
|
988
|
+
return values_1.ERRORS.DIV0;
|
|
989
|
+
}
|
|
990
|
+
return [(a[0] * b[0] + a[1] * b[1]) / denom, (a[1] * b[0] - a[0] * b[1]) / denom];
|
|
991
|
+
}
|
|
992
|
+
const fnIMTAN = args => unaryComplex(args, (re, im) => {
|
|
993
|
+
// tan(z) = sin(z) / cos(z)
|
|
994
|
+
const sinZ = [Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)];
|
|
995
|
+
const cosZ = [Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)];
|
|
996
|
+
return cdiv(sinZ, cosZ);
|
|
997
|
+
});
|
|
998
|
+
exports.fnIMTAN = fnIMTAN;
|
|
999
|
+
const fnIMCSC = args => unaryComplex(args, (re, im) => {
|
|
1000
|
+
// csc(z) = 1 / sin(z)
|
|
1001
|
+
const sinZ = [Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)];
|
|
1002
|
+
return cdiv([1, 0], sinZ);
|
|
1003
|
+
});
|
|
1004
|
+
exports.fnIMCSC = fnIMCSC;
|
|
1005
|
+
const fnIMSEC = args => unaryComplex(args, (re, im) => {
|
|
1006
|
+
// sec(z) = 1 / cos(z)
|
|
1007
|
+
const cosZ = [Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)];
|
|
1008
|
+
return cdiv([1, 0], cosZ);
|
|
1009
|
+
});
|
|
1010
|
+
exports.fnIMSEC = fnIMSEC;
|
|
1011
|
+
const fnIMCOT = args => unaryComplex(args, (re, im) => {
|
|
1012
|
+
// cot(z) = cos(z) / sin(z)
|
|
1013
|
+
const sinZ = [Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)];
|
|
1014
|
+
const cosZ = [Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)];
|
|
1015
|
+
return cdiv(cosZ, sinZ);
|
|
1016
|
+
});
|
|
1017
|
+
exports.fnIMCOT = fnIMCOT;
|
|
1018
|
+
const fnIMSINH = args => unaryComplex(args, (re, im) => [Math.sinh(re) * Math.cos(im), Math.cosh(re) * Math.sin(im)]);
|
|
1019
|
+
exports.fnIMSINH = fnIMSINH;
|
|
1020
|
+
const fnIMCOSH = args => unaryComplex(args, (re, im) => [Math.cosh(re) * Math.cos(im), Math.sinh(re) * Math.sin(im)]);
|
|
1021
|
+
exports.fnIMCOSH = fnIMCOSH;
|
|
1022
|
+
const fnIMTANH = args => unaryComplex(args, (re, im) => {
|
|
1023
|
+
// tanh(z) = sinh(z) / cosh(z)
|
|
1024
|
+
const sinhZ = [Math.sinh(re) * Math.cos(im), Math.cosh(re) * Math.sin(im)];
|
|
1025
|
+
const coshZ = [Math.cosh(re) * Math.cos(im), Math.sinh(re) * Math.sin(im)];
|
|
1026
|
+
return cdiv(sinhZ, coshZ);
|
|
1027
|
+
});
|
|
1028
|
+
exports.fnIMTANH = fnIMTANH;
|
|
1029
|
+
const fnIMCSCH = args => unaryComplex(args, (re, im) => {
|
|
1030
|
+
const sinhZ = [Math.sinh(re) * Math.cos(im), Math.cosh(re) * Math.sin(im)];
|
|
1031
|
+
return cdiv([1, 0], sinhZ);
|
|
1032
|
+
});
|
|
1033
|
+
exports.fnIMCSCH = fnIMCSCH;
|
|
1034
|
+
const fnIMSECH = args => unaryComplex(args, (re, im) => {
|
|
1035
|
+
const coshZ = [Math.cosh(re) * Math.cos(im), Math.sinh(re) * Math.sin(im)];
|
|
1036
|
+
return cdiv([1, 0], coshZ);
|
|
1037
|
+
});
|
|
1038
|
+
exports.fnIMSECH = fnIMSECH;
|
|
1039
|
+
const fnIMCOTH = args => unaryComplex(args, (re, im) => {
|
|
1040
|
+
const sinhZ = [Math.sinh(re) * Math.cos(im), Math.cosh(re) * Math.sin(im)];
|
|
1041
|
+
const coshZ = [Math.cosh(re) * Math.cos(im), Math.sinh(re) * Math.sin(im)];
|
|
1042
|
+
return cdiv(coshZ, sinhZ);
|
|
1043
|
+
});
|
|
1044
|
+
exports.fnIMCOTH = fnIMCOTH;
|
|
1045
|
+
// Excel's bitwise family (BITAND/BITOR/BITXOR/BITLSHIFT/BITRSHIFT) operates
|
|
1046
|
+
// on integers in the range [0, 2^48 − 1]. JavaScript's `&`/`|`/`^` truncate
|
|
1047
|
+
// to 32 bits, so we emulate 48-bit semantics by splitting each operand into
|
|
1048
|
+
// a 24-bit low half and a 24-bit high half, combining those halves with
|
|
1049
|
+
// native 32-bit bitwise ops, and recombining. The shift functions use the
|
|
1050
|
+
// same split so `BITLSHIFT(2^30, 10)` doesn't silently lose bits.
|
|
1051
|
+
const BIT_MAX = 2 ** 48 - 1;
|
|
1052
|
+
function bitOp(op) {
|
|
1053
|
+
return (a, b) => {
|
|
1054
|
+
const aHi = Math.floor(a / 0x1000000);
|
|
1055
|
+
const aLo = a - aHi * 0x1000000;
|
|
1056
|
+
const bHi = Math.floor(b / 0x1000000);
|
|
1057
|
+
const bLo = b - bHi * 0x1000000;
|
|
1058
|
+
return op(aHi, bHi) * 0x1000000 + (op(aLo, bLo) >>> 0);
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
1061
|
+
const bitAnd48 = bitOp((a, b) => (a & b) >>> 0);
|
|
1062
|
+
const bitOr48 = bitOp((a, b) => (a | b) >>> 0);
|
|
1063
|
+
const bitXor48 = bitOp((a, b) => (a ^ b) >>> 0);
|
|
1064
|
+
function validateBitOperand(v) {
|
|
1065
|
+
if (v < 0 || v > BIT_MAX) {
|
|
1066
|
+
return values_1.ERRORS.NUM;
|
|
1067
|
+
}
|
|
1068
|
+
// Excel rejects non-integer operands with #NUM!, rather than silently
|
|
1069
|
+
// truncating. Use the strict `v !== floor(v)` check so `5.9` does not
|
|
1070
|
+
// pass as `5`.
|
|
1071
|
+
if (v !== Math.floor(v)) {
|
|
1072
|
+
return values_1.ERRORS.NUM;
|
|
1073
|
+
}
|
|
1074
|
+
return v;
|
|
1075
|
+
}
|
|
1076
|
+
const fnBITAND = args => {
|
|
1077
|
+
const a = (0, values_1.toNumberRV)(args[0]);
|
|
1078
|
+
if ((0, values_1.isError)(a)) {
|
|
1079
|
+
return a;
|
|
1080
|
+
}
|
|
1081
|
+
const b = (0, values_1.toNumberRV)(args[1]);
|
|
1082
|
+
if ((0, values_1.isError)(b)) {
|
|
1083
|
+
return b;
|
|
1084
|
+
}
|
|
1085
|
+
const av = validateBitOperand(a.value);
|
|
1086
|
+
if (typeof av !== "number") {
|
|
1087
|
+
return av;
|
|
1088
|
+
}
|
|
1089
|
+
const bv = validateBitOperand(b.value);
|
|
1090
|
+
if (typeof bv !== "number") {
|
|
1091
|
+
return bv;
|
|
1092
|
+
}
|
|
1093
|
+
return (0, values_1.rvNumber)(bitAnd48(av, bv));
|
|
1094
|
+
};
|
|
1095
|
+
exports.fnBITAND = fnBITAND;
|
|
1096
|
+
const fnBITOR = args => {
|
|
1097
|
+
const a = (0, values_1.toNumberRV)(args[0]);
|
|
1098
|
+
if ((0, values_1.isError)(a)) {
|
|
1099
|
+
return a;
|
|
1100
|
+
}
|
|
1101
|
+
const b = (0, values_1.toNumberRV)(args[1]);
|
|
1102
|
+
if ((0, values_1.isError)(b)) {
|
|
1103
|
+
return b;
|
|
1104
|
+
}
|
|
1105
|
+
const av = validateBitOperand(a.value);
|
|
1106
|
+
if (typeof av !== "number") {
|
|
1107
|
+
return av;
|
|
1108
|
+
}
|
|
1109
|
+
const bv = validateBitOperand(b.value);
|
|
1110
|
+
if (typeof bv !== "number") {
|
|
1111
|
+
return bv;
|
|
1112
|
+
}
|
|
1113
|
+
return (0, values_1.rvNumber)(bitOr48(av, bv));
|
|
1114
|
+
};
|
|
1115
|
+
exports.fnBITOR = fnBITOR;
|
|
1116
|
+
const fnBITXOR = args => {
|
|
1117
|
+
const a = (0, values_1.toNumberRV)(args[0]);
|
|
1118
|
+
if ((0, values_1.isError)(a)) {
|
|
1119
|
+
return a;
|
|
1120
|
+
}
|
|
1121
|
+
const b = (0, values_1.toNumberRV)(args[1]);
|
|
1122
|
+
if ((0, values_1.isError)(b)) {
|
|
1123
|
+
return b;
|
|
1124
|
+
}
|
|
1125
|
+
const av = validateBitOperand(a.value);
|
|
1126
|
+
if (typeof av !== "number") {
|
|
1127
|
+
return av;
|
|
1128
|
+
}
|
|
1129
|
+
const bv = validateBitOperand(b.value);
|
|
1130
|
+
if (typeof bv !== "number") {
|
|
1131
|
+
return bv;
|
|
1132
|
+
}
|
|
1133
|
+
return (0, values_1.rvNumber)(bitXor48(av, bv));
|
|
1134
|
+
};
|
|
1135
|
+
exports.fnBITXOR = fnBITXOR;
|
|
1136
|
+
const fnBITLSHIFT = args => {
|
|
1137
|
+
const num = (0, values_1.toNumberRV)(args[0]);
|
|
1138
|
+
if ((0, values_1.isError)(num)) {
|
|
1139
|
+
return num;
|
|
1140
|
+
}
|
|
1141
|
+
const shift = (0, values_1.toNumberRV)(args[1]);
|
|
1142
|
+
if ((0, values_1.isError)(shift)) {
|
|
1143
|
+
return shift;
|
|
1144
|
+
}
|
|
1145
|
+
const nv = validateBitOperand(num.value);
|
|
1146
|
+
if (typeof nv !== "number") {
|
|
1147
|
+
return nv;
|
|
1148
|
+
}
|
|
1149
|
+
const s = Math.trunc(shift.value);
|
|
1150
|
+
if (s < -53 || s > 53) {
|
|
1151
|
+
return values_1.ERRORS.NUM;
|
|
1152
|
+
}
|
|
1153
|
+
const result = s >= 0 ? nv * Math.pow(2, s) : Math.floor(nv / Math.pow(2, -s));
|
|
1154
|
+
if (result > BIT_MAX) {
|
|
1155
|
+
return values_1.ERRORS.NUM;
|
|
1156
|
+
}
|
|
1157
|
+
return (0, values_1.rvNumber)(result);
|
|
1158
|
+
};
|
|
1159
|
+
exports.fnBITLSHIFT = fnBITLSHIFT;
|
|
1160
|
+
const fnBITRSHIFT = args => {
|
|
1161
|
+
const num = (0, values_1.toNumberRV)(args[0]);
|
|
1162
|
+
if ((0, values_1.isError)(num)) {
|
|
1163
|
+
return num;
|
|
1164
|
+
}
|
|
1165
|
+
const shift = (0, values_1.toNumberRV)(args[1]);
|
|
1166
|
+
if ((0, values_1.isError)(shift)) {
|
|
1167
|
+
return shift;
|
|
1168
|
+
}
|
|
1169
|
+
const nv = validateBitOperand(num.value);
|
|
1170
|
+
if (typeof nv !== "number") {
|
|
1171
|
+
return nv;
|
|
1172
|
+
}
|
|
1173
|
+
const s = Math.trunc(shift.value);
|
|
1174
|
+
if (s < -53 || s > 53) {
|
|
1175
|
+
return values_1.ERRORS.NUM;
|
|
1176
|
+
}
|
|
1177
|
+
const result = s >= 0 ? Math.floor(nv / Math.pow(2, s)) : nv * Math.pow(2, -s);
|
|
1178
|
+
if (result > BIT_MAX) {
|
|
1179
|
+
return values_1.ERRORS.NUM;
|
|
1180
|
+
}
|
|
1181
|
+
return (0, values_1.rvNumber)(result);
|
|
1182
|
+
};
|
|
1183
|
+
exports.fnBITRSHIFT = fnBITRSHIFT;
|