From cdcfad8f1e7db751f5521a2f8a9303b0535aaf34 Mon Sep 17 00:00:00 2001 From: wpxp123456 Date: Sat, 26 Oct 2024 16:58:15 +0800 Subject: [PATCH] fix(formula): fix bug --- .../engine-formula/src/basics/statistical.ts | 4 ++ .../hypgeomdist/__tests__/index.spec.ts | 44 ++++++++++++++++++ .../compatibility/negbinomdist/index.ts | 4 +- .../geomean/__tests__/index.spec.ts | 6 +-- .../functions/statistical/geomean/index.ts | 12 ++++- .../harmean/__tests__/index.spec.ts | 6 +-- .../functions/statistical/harmean/index.ts | 8 ++++ .../hypgeom-dist/__tests__/index.spec.ts | 45 +++++++++++++++++++ .../statistical/kurt/__tests__/index.spec.ts | 6 +-- .../src/functions/statistical/kurt/index.ts | 16 ++++++- .../statistical/large/__tests__/index.spec.ts | 17 +++++++ .../src/functions/statistical/large/index.ts | 6 +-- .../lognorm-inv/__tests__/index.spec.ts | 8 ++++ .../statistical/lognorm-inv/index.ts | 6 ++- .../median/__tests__/index.spec.ts | 16 +++++-- .../src/functions/statistical/median/index.ts | 12 ++++- .../mode-mult/__tests__/index.spec.ts | 6 +-- .../functions/statistical/mode-mult/index.ts | 14 +++++- .../mode-sngl/__tests__/index.spec.ts | 6 +-- .../functions/statistical/mode-sngl/index.ts | 16 ++++++- .../negbinom-dist/__tests__/index.spec.ts | 8 ++++ .../statistical/negbinom-dist/index.ts | 4 +- .../percentile-exc/__tests__/index.spec.ts | 17 +++++++ .../statistical/percentile-exc/index.ts | 6 +-- .../percentile-inc/__tests__/index.spec.ts | 17 +++++++ .../statistical/percentile-inc/index.ts | 6 +-- .../skew-p/__tests__/index.spec.ts | 6 +-- .../src/functions/statistical/skew-p/index.ts | 16 ++++++- .../statistical/skew/__tests__/index.spec.ts | 6 +-- .../src/functions/statistical/skew/index.ts | 16 ++++++- .../statistical/small/__tests__/index.spec.ts | 17 +++++++ .../src/functions/statistical/small/index.ts | 6 +-- .../z-test/__tests__/index.spec.ts | 17 +++++++ .../src/functions/statistical/z-test/index.ts | 4 +- 34 files changed, 348 insertions(+), 56 deletions(-) diff --git a/packages/engine-formula/src/basics/statistical.ts b/packages/engine-formula/src/basics/statistical.ts index cd4e5d14357..140555604b7 100644 --- a/packages/engine-formula/src/basics/statistical.ts +++ b/packages/engine-formula/src/basics/statistical.ts @@ -617,6 +617,10 @@ export function hypergeometricCDF(x: number, n: number, M: number, N: number): n } export function hypergeometricPDF(x: number, n: number, M: number, N: number): number { + if (n - x > N - M) { + return 0; + } + return calculateCombin(M, x) * calculateCombin(N - M, n - x) / calculateCombin(N, n); } diff --git a/packages/engine-formula/src/functions/compatibility/hypgeomdist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/compatibility/hypgeomdist/__tests__/index.spec.ts index 5083b1aa0e2..cb9e2917abd 100644 --- a/packages/engine-formula/src/functions/compatibility/hypgeomdist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/compatibility/hypgeomdist/__tests__/index.spec.ts @@ -179,6 +179,50 @@ describe('Test hypgeomdist function', () => { [0.3632610939112487, ErrorType.VALUE, 0.3632610939112487, 0.3632610939112487, 0.1021671826625387, 0.1021671826625387], [0.1021671826625387, ErrorType.NUM, 0.3814241486068111, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], ]); + + const sampleS2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [4], + [8], + [20], + ]), + rowCount: 4, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberSample2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [4], + [8], + [20], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(sampleS2, numberSample2, populationS, numberPop); + expect(getObjectValue(result2)).toStrictEqual([ + [0.3632610939112487], + [0.27506549178375805], + [1], + [ErrorType.NA], + ]); + }); + + it('More test', () => { + const sampleS = NumberValueObject.create(20); + const numberSample = NumberValueObject.create(20); + const populationS = NumberValueObject.create(20); + const numberPop = NumberValueObject.create(20); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toBe(1); }); }); }); diff --git a/packages/engine-formula/src/functions/compatibility/negbinomdist/index.ts b/packages/engine-formula/src/functions/compatibility/negbinomdist/index.ts index 42efa3e0aa6..e9d439dcb03 100644 --- a/packages/engine-formula/src/functions/compatibility/negbinomdist/index.ts +++ b/packages/engine-formula/src/functions/compatibility/negbinomdist/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { ErrorType } from '../../../basics/error-type'; import { negbinomialPDF } from '../../../basics/statistical'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; @@ -21,7 +22,6 @@ import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check- import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; export class Negbinomdist extends BaseFunction { override minParams = 3; @@ -92,7 +92,7 @@ export class Negbinomdist extends BaseFunction { const numberSValue = Math.floor(+_numberSObject.getValue()); const probabilitySValue = +_probabilitySObject.getValue(); - if (numberFValue < 0 || numberSValue < 1 || probabilitySValue < 0 || probabilitySValue > 1) { + if (numberFValue < 0 || numberSValue < 1 || probabilitySValue <= 0 || probabilitySValue >= 1) { return ErrorValueObject.create(ErrorType.NUM); } diff --git a/packages/engine-formula/src/functions/statistical/geomean/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/geomean/__tests__/index.spec.ts index 788f62342f0..a0297ac7a6f 100644 --- a/packages/engine-formula/src/functions/statistical/geomean/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/geomean/__tests__/index.spec.ts @@ -53,12 +53,12 @@ describe('Test geomean function', () => { const number5 = ErrorValueObject.create(ErrorType.NAME); const number6 = NumberValueObject.create(-3); const result = testFunction.calculate(number, number2, number3, number4); - expect(getObjectValue(result)).toStrictEqual(3); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); - const result2 = testFunction.calculate(number, number2, number3, number4, number5); + const result2 = testFunction.calculate(number, number2, number3, number5); expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); - const result3 = testFunction.calculate(number, number2, number3, number4, number6); + const result3 = testFunction.calculate(number, number2, number3, number6); expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); }); diff --git a/packages/engine-formula/src/functions/statistical/geomean/index.ts b/packages/engine-formula/src/functions/statistical/geomean/index.ts index 17150193a27..50798cb5a82 100644 --- a/packages/engine-formula/src/functions/statistical/geomean/index.ts +++ b/packages/engine-formula/src/functions/statistical/geomean/index.ts @@ -14,13 +14,13 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class Geomean extends BaseFunction { override minParams = 1; @@ -72,6 +72,14 @@ export class Geomean extends BaseFunction { return variant; } + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + if (variant.isNull() || variant.isBoolean()) { continue; } diff --git a/packages/engine-formula/src/functions/statistical/harmean/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/harmean/__tests__/index.spec.ts index f6495cdf9ac..8e269e35856 100644 --- a/packages/engine-formula/src/functions/statistical/harmean/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/harmean/__tests__/index.spec.ts @@ -53,12 +53,12 @@ describe('Test harmean function', () => { const number5 = ErrorValueObject.create(ErrorType.NAME); const number6 = NumberValueObject.create(-3); const result = testFunction.calculate(number, number2, number3, number4); - expect(getObjectValue(result)).toStrictEqual(3); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); - const result2 = testFunction.calculate(number, number2, number3, number4, number5); + const result2 = testFunction.calculate(number, number2, number3, number5); expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); - const result3 = testFunction.calculate(number, number2, number3, number4, number6); + const result3 = testFunction.calculate(number, number2, number3, number6); expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); }); diff --git a/packages/engine-formula/src/functions/statistical/harmean/index.ts b/packages/engine-formula/src/functions/statistical/harmean/index.ts index 321855a89f3..84cac8310b2 100644 --- a/packages/engine-formula/src/functions/statistical/harmean/index.ts +++ b/packages/engine-formula/src/functions/statistical/harmean/index.ts @@ -72,6 +72,14 @@ export class Harmean extends BaseFunction { return variant; } + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + if (variant.isNull() || variant.isBoolean()) { continue; } diff --git a/packages/engine-formula/src/functions/statistical/hypgeom-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/hypgeom-dist/__tests__/index.spec.ts index 2dbb47f6f86..51d18d46835 100644 --- a/packages/engine-formula/src/functions/statistical/hypgeom-dist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/hypgeom-dist/__tests__/index.spec.ts @@ -208,6 +208,51 @@ describe('Test hypgeomDist function', () => { [0.46542827657378744, ErrorType.VALUE, 0.46542827657378744, 0.46542827657378744, 0.1021671826625387, 0.1021671826625387], [0.1021671826625387, ErrorType.NUM, 0.8468524251805986, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], ]); + + const sampleS2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [4], + [8], + [20], + ]), + rowCount: 4, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberSample2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [4], + [8], + [20], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(sampleS2, numberSample2, populationS, numberPop, cumulative); + expect(getObjectValue(result2)).toStrictEqual([ + [0.46542827657378744], + [0.8867587520838295], + [1], + [ErrorType.NA], + ]); + }); + + it('More test', () => { + const sampleS = NumberValueObject.create(20); + const numberSample = NumberValueObject.create(20); + const populationS = NumberValueObject.create(20); + const numberPop = NumberValueObject.create(20); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(1); }); }); }); diff --git a/packages/engine-formula/src/functions/statistical/kurt/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/kurt/__tests__/index.spec.ts index 09b21aeb37f..2e99a6749b4 100644 --- a/packages/engine-formula/src/functions/statistical/kurt/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/kurt/__tests__/index.spec.ts @@ -70,12 +70,12 @@ describe('Test kurt function', () => { const number5 = ErrorValueObject.create(ErrorType.NAME); const number6 = NumberValueObject.create(-3); const result = testFunction.calculate(number, number2, number3, number4); - expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); - const result2 = testFunction.calculate(number, number2, number3, number4, number5); + const result2 = testFunction.calculate(number, number2, number3, number5); expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); - const result3 = testFunction.calculate(number, number2, number3, number4, number6); + const result3 = testFunction.calculate(number, number2, number3, number6); expect(getObjectValue(result3)).toStrictEqual(ErrorType.DIV_BY_ZERO); }); diff --git a/packages/engine-formula/src/functions/statistical/kurt/index.ts b/packages/engine-formula/src/functions/statistical/kurt/index.ts index b4ba78dc067..f8419e1a617 100644 --- a/packages/engine-formula/src/functions/statistical/kurt/index.ts +++ b/packages/engine-formula/src/functions/statistical/kurt/index.ts @@ -14,13 +14,13 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class Kurt extends BaseFunction { override minParams = 1; @@ -35,6 +35,18 @@ export class Kurt extends BaseFunction { for (let i = 0; i < variants.length; i++) { const variant = variants[i]; + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + const rowCount = variant.isArray() ? (variant as ArrayValueObject).getRowCount() : 1; const columnCount = variant.isArray() ? (variant as ArrayValueObject).getColumnCount() : 1; diff --git a/packages/engine-formula/src/functions/statistical/large/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/large/__tests__/index.spec.ts index e1c43389c3d..a05d870a9a9 100644 --- a/packages/engine-formula/src/functions/statistical/large/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/large/__tests__/index.spec.ts @@ -45,6 +45,23 @@ describe('Test large function', () => { expect(getObjectValue(result)).toStrictEqual(8); }); + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'1', '\'2', '\'3', '\'4', '\'5', '\'6', '\'7', '\'8', '\'9', '\'10'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(2.5); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + it('Array value test', () => { const array = ArrayValueObject.create({ calculateValueList: transformToValueObject([ diff --git a/packages/engine-formula/src/functions/statistical/large/index.ts b/packages/engine-formula/src/functions/statistical/large/index.ts index 54de92dcd20..da4740530ba 100644 --- a/packages/engine-formula/src/functions/statistical/large/index.ts +++ b/packages/engine-formula/src/functions/statistical/large/index.ts @@ -14,14 +14,14 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class Large extends BaseFunction { override minParams = 2; @@ -82,7 +82,7 @@ export class Large extends BaseFunction { return valueObject as ErrorValueObject; } - if (valueObject.isNull() || valueObject.isBoolean()) { + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { continue; } diff --git a/packages/engine-formula/src/functions/statistical/lognorm-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/lognorm-inv/__tests__/index.spec.ts index 81b542f1592..a45c7531980 100644 --- a/packages/engine-formula/src/functions/statistical/lognorm-inv/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/lognorm-inv/__tests__/index.spec.ts @@ -106,5 +106,13 @@ describe('Test lognormInv function', () => { [ErrorType.NUM, ErrorType.NUM, ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], ]); }); + + it('More test', () => { + const probability = NumberValueObject.create(0.012548); + const mean = NumberValueObject.create(100000); + const standardDev = NumberValueObject.create(1.987); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); }); }); diff --git a/packages/engine-formula/src/functions/statistical/lognorm-inv/index.ts b/packages/engine-formula/src/functions/statistical/lognorm-inv/index.ts index 298ec3cf3ab..c03b74b59bc 100644 --- a/packages/engine-formula/src/functions/statistical/lognorm-inv/index.ts +++ b/packages/engine-formula/src/functions/statistical/lognorm-inv/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { ErrorType } from '../../../basics/error-type'; import { lognormalINV } from '../../../basics/statistical'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; @@ -21,7 +22,6 @@ import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check- import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; export class LognormInv extends BaseFunction { override minParams = 3; @@ -98,6 +98,10 @@ export class LognormInv extends BaseFunction { const result = lognormalINV(probabilityValue, meanValue, standardDevValue); + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + return NumberValueObject.create(result); } } diff --git a/packages/engine-formula/src/functions/statistical/median/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/median/__tests__/index.spec.ts index 4a195c90db4..99a22d51ee8 100644 --- a/packages/engine-formula/src/functions/statistical/median/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/median/__tests__/index.spec.ts @@ -54,12 +54,12 @@ describe('Test median function', () => { const number5 = ErrorValueObject.create(ErrorType.NAME); const number6 = NumberValueObject.create(-3); const result = testFunction.calculate(number, number2, number3, number4); - expect(getObjectValue(result)).toStrictEqual(3); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); - const result2 = testFunction.calculate(number, number2, number3, number4, number5); + const result2 = testFunction.calculate(number, number2, number3, number5); expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); - const result3 = testFunction.calculate(number, number2, number3, number4, number6); + const result3 = testFunction.calculate(number, number2, number3, number6); expect(getObjectValue(result3)).toStrictEqual(0); }); @@ -94,6 +94,16 @@ describe('Test median function', () => { }); const result = testFunction.calculate(number); expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const number2 = NumberValueObject.create(1); + const number3 = NumberValueObject.create(2); + const number4 = StringValueObject.create('3'); + const result2 = testFunction.calculate(number2, number3, number4); + expect(getObjectValue(result2)).toStrictEqual(2); + + const number5 = StringValueObject.create('test'); + const result3 = testFunction.calculate(number2, number3, number5); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.VALUE); }); }); }); diff --git a/packages/engine-formula/src/functions/statistical/median/index.ts b/packages/engine-formula/src/functions/statistical/median/index.ts index 9f6fc39aec1..6ab4b36b5f5 100644 --- a/packages/engine-formula/src/functions/statistical/median/index.ts +++ b/packages/engine-formula/src/functions/statistical/median/index.ts @@ -14,13 +14,13 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class Median extends BaseFunction { override minParams = 1; @@ -69,6 +69,14 @@ export class Median extends BaseFunction { continue; } + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + const value = variant.getValue(); if (!isRealNum(value)) { diff --git a/packages/engine-formula/src/functions/statistical/mode-mult/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/mode-mult/__tests__/index.spec.ts index 7b0f5db6cf8..41fc4c06140 100644 --- a/packages/engine-formula/src/functions/statistical/mode-mult/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/mode-mult/__tests__/index.spec.ts @@ -74,12 +74,12 @@ describe('Test modeMult function', () => { const number5 = ErrorValueObject.create(ErrorType.NAME); const number6 = NumberValueObject.create(-3); const result = testFunction.calculate(number, number2, number3, number4); - expect(getObjectValue(result)).toStrictEqual(ErrorType.NA); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); - const result2 = testFunction.calculate(number, number2, number3, number4, number5); + const result2 = testFunction.calculate(number, number2, number3, number5); expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); - const result3 = testFunction.calculate(number, number2, number3, number4, number6); + const result3 = testFunction.calculate(number, number2, number3, number6); expect(getObjectValue(result3)).toStrictEqual(ErrorType.NA); }); diff --git a/packages/engine-formula/src/functions/statistical/mode-mult/index.ts b/packages/engine-formula/src/functions/statistical/mode-mult/index.ts index 54c18b40486..fc4b310ae07 100644 --- a/packages/engine-formula/src/functions/statistical/mode-mult/index.ts +++ b/packages/engine-formula/src/functions/statistical/mode-mult/index.ts @@ -14,13 +14,13 @@ * limitations under the License. */ +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; type valueMapType = Record { const number5 = ErrorValueObject.create(ErrorType.NAME); const number6 = NumberValueObject.create(-3); const result = testFunction.calculate(number, number2, number3, number4); - expect(getObjectValue(result)).toStrictEqual(ErrorType.NA); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); - const result2 = testFunction.calculate(number, number2, number3, number4, number5); + const result2 = testFunction.calculate(number, number2, number3, number5); expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); - const result3 = testFunction.calculate(number, number2, number3, number4, number6); + const result3 = testFunction.calculate(number, number2, number3, number6); expect(getObjectValue(result3)).toStrictEqual(ErrorType.NA); }); diff --git a/packages/engine-formula/src/functions/statistical/mode-sngl/index.ts b/packages/engine-formula/src/functions/statistical/mode-sngl/index.ts index 7edf373e1d3..ac05bf268d9 100644 --- a/packages/engine-formula/src/functions/statistical/mode-sngl/index.ts +++ b/packages/engine-formula/src/functions/statistical/mode-sngl/index.ts @@ -14,13 +14,13 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; type valueMapType = Record { const probabilityS2 = NumberValueObject.create(1.5); const result2 = testFunction.calculate(numberF, numberS, probabilityS2, cumulative); expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const probabilityS3 = NumberValueObject.create(0); + const result3 = testFunction.calculate(numberF, numberS, probabilityS3, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NUM); + + const probabilityS4 = NumberValueObject.create(1); + const result4 = testFunction.calculate(numberF, numberS, probabilityS4, cumulative); + expect(getObjectValue(result4)).toBe(ErrorType.NUM); }); it('Cumulative value test', () => { diff --git a/packages/engine-formula/src/functions/statistical/negbinom-dist/index.ts b/packages/engine-formula/src/functions/statistical/negbinom-dist/index.ts index 2dc359e7eb4..e9eec0cf3ea 100644 --- a/packages/engine-formula/src/functions/statistical/negbinom-dist/index.ts +++ b/packages/engine-formula/src/functions/statistical/negbinom-dist/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { ErrorType } from '../../../basics/error-type'; import { negbinomialCDF, negbinomialPDF } from '../../../basics/statistical'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; @@ -21,7 +22,6 @@ import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check- import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; export class NegbinomDist extends BaseFunction { override minParams = 4; @@ -103,7 +103,7 @@ export class NegbinomDist extends BaseFunction { const probabilitySValue = +_probabilitySObject.getValue(); const cumulativeValue = +_cumulativeObject.getValue(); - if (numberFValue < 0 || numberSValue < 1 || probabilitySValue < 0 || probabilitySValue > 1) { + if (numberFValue < 0 || numberSValue < 1 || probabilitySValue <= 0 || probabilitySValue >= 1) { return ErrorValueObject.create(ErrorType.NUM); } diff --git a/packages/engine-formula/src/functions/statistical/percentile-exc/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/percentile-exc/__tests__/index.spec.ts index 167ce913902..0dc07d91231 100644 --- a/packages/engine-formula/src/functions/statistical/percentile-exc/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/percentile-exc/__tests__/index.spec.ts @@ -45,6 +45,23 @@ describe('Test percentileExc function', () => { expect(getObjectValue(result)).toStrictEqual(3.3); }); + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'1', '\'2', '\'3', '\'4', '\'5', '\'6', '\'7', '\'8', '\'9', '\'10'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + it('Array value test', () => { const array = ArrayValueObject.create({ calculateValueList: transformToValueObject([ diff --git a/packages/engine-formula/src/functions/statistical/percentile-exc/index.ts b/packages/engine-formula/src/functions/statistical/percentile-exc/index.ts index 0bbf15e42aa..7e41a55c9c4 100644 --- a/packages/engine-formula/src/functions/statistical/percentile-exc/index.ts +++ b/packages/engine-formula/src/functions/statistical/percentile-exc/index.ts @@ -14,14 +14,14 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class PercentileExc extends BaseFunction { override minParams = 2; @@ -92,7 +92,7 @@ export class PercentileExc extends BaseFunction { return valueObject as ErrorValueObject; } - if (valueObject.isNull() || valueObject.isBoolean()) { + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { continue; } diff --git a/packages/engine-formula/src/functions/statistical/percentile-inc/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/percentile-inc/__tests__/index.spec.ts index 686da04f7fa..c72fd8f41d9 100644 --- a/packages/engine-formula/src/functions/statistical/percentile-inc/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/percentile-inc/__tests__/index.spec.ts @@ -45,6 +45,23 @@ describe('Test percentileInc function', () => { expect(getObjectValue(result)).toStrictEqual(3.6999999999999997); }); + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'1', '\'2', '\'3', '\'4', '\'5', '\'6', '\'7', '\'8', '\'9', '\'10'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + it('Array value test', () => { const array = ArrayValueObject.create({ calculateValueList: transformToValueObject([ diff --git a/packages/engine-formula/src/functions/statistical/percentile-inc/index.ts b/packages/engine-formula/src/functions/statistical/percentile-inc/index.ts index 7ae176e4bd0..5cd737af8a1 100644 --- a/packages/engine-formula/src/functions/statistical/percentile-inc/index.ts +++ b/packages/engine-formula/src/functions/statistical/percentile-inc/index.ts @@ -14,14 +14,14 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class PercentileInc extends BaseFunction { override minParams = 2; @@ -92,7 +92,7 @@ export class PercentileInc extends BaseFunction { return valueObject as ErrorValueObject; } - if (valueObject.isNull() || valueObject.isBoolean()) { + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { continue; } diff --git a/packages/engine-formula/src/functions/statistical/skew-p/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/skew-p/__tests__/index.spec.ts index 8d90764a8c9..1ce85c3724e 100644 --- a/packages/engine-formula/src/functions/statistical/skew-p/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/skew-p/__tests__/index.spec.ts @@ -70,12 +70,12 @@ describe('Test skewP function', () => { const number5 = ErrorValueObject.create(ErrorType.NAME); const number6 = NumberValueObject.create(-3); const result = testFunction.calculate(number, number2, number3, number4); - expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); - const result2 = testFunction.calculate(number, number2, number3, number4, number5); + const result2 = testFunction.calculate(number, number2, number3, number5); expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); - const result3 = testFunction.calculate(number, number2, number3, number4, number6); + const result3 = testFunction.calculate(number, number2, number3, number6); expect(getObjectValue(result3)).toStrictEqual(ErrorType.DIV_BY_ZERO); }); diff --git a/packages/engine-formula/src/functions/statistical/skew-p/index.ts b/packages/engine-formula/src/functions/statistical/skew-p/index.ts index 73e0c105c7f..5d08985739c 100644 --- a/packages/engine-formula/src/functions/statistical/skew-p/index.ts +++ b/packages/engine-formula/src/functions/statistical/skew-p/index.ts @@ -14,13 +14,13 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class SkewP extends BaseFunction { override minParams = 1; @@ -35,6 +35,18 @@ export class SkewP extends BaseFunction { for (let i = 0; i < variants.length; i++) { const variant = variants[i]; + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + const rowCount = variant.isArray() ? (variant as ArrayValueObject).getRowCount() : 1; const columnCount = variant.isArray() ? (variant as ArrayValueObject).getColumnCount() : 1; diff --git a/packages/engine-formula/src/functions/statistical/skew/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/skew/__tests__/index.spec.ts index d4870d4eff5..00885267960 100644 --- a/packages/engine-formula/src/functions/statistical/skew/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/skew/__tests__/index.spec.ts @@ -70,12 +70,12 @@ describe('Test skew function', () => { const number5 = ErrorValueObject.create(ErrorType.NAME); const number6 = NumberValueObject.create(-3); const result = testFunction.calculate(number, number2, number3, number4); - expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); - const result2 = testFunction.calculate(number, number2, number3, number4, number5); + const result2 = testFunction.calculate(number, number2, number3, number5); expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); - const result3 = testFunction.calculate(number, number2, number3, number4, number6); + const result3 = testFunction.calculate(number, number2, number3, number6); expect(getObjectValue(result3)).toStrictEqual(ErrorType.DIV_BY_ZERO); }); diff --git a/packages/engine-formula/src/functions/statistical/skew/index.ts b/packages/engine-formula/src/functions/statistical/skew/index.ts index dd6956e53e0..58190ba6220 100644 --- a/packages/engine-formula/src/functions/statistical/skew/index.ts +++ b/packages/engine-formula/src/functions/statistical/skew/index.ts @@ -14,13 +14,13 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class Skew extends BaseFunction { override minParams = 1; @@ -35,6 +35,18 @@ export class Skew extends BaseFunction { for (let i = 0; i < variants.length; i++) { const variant = variants[i]; + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + const rowCount = variant.isArray() ? (variant as ArrayValueObject).getRowCount() : 1; const columnCount = variant.isArray() ? (variant as ArrayValueObject).getColumnCount() : 1; diff --git a/packages/engine-formula/src/functions/statistical/small/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/small/__tests__/index.spec.ts index 8b7611e2f76..880ab88cef6 100644 --- a/packages/engine-formula/src/functions/statistical/small/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/small/__tests__/index.spec.ts @@ -45,6 +45,23 @@ describe('Test small function', () => { expect(getObjectValue(result)).toStrictEqual(3); }); + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'1', '\'2', '\'3', '\'4', '\'5', '\'6', '\'7', '\'8', '\'9', '\'10'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(2.5); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + it('Array value test', () => { const array = ArrayValueObject.create({ calculateValueList: transformToValueObject([ diff --git a/packages/engine-formula/src/functions/statistical/small/index.ts b/packages/engine-formula/src/functions/statistical/small/index.ts index c5288b41637..cb52e3c35db 100644 --- a/packages/engine-formula/src/functions/statistical/small/index.ts +++ b/packages/engine-formula/src/functions/statistical/small/index.ts @@ -14,14 +14,14 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; -import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; export class Small extends BaseFunction { override minParams = 2; @@ -82,7 +82,7 @@ export class Small extends BaseFunction { return valueObject as ErrorValueObject; } - if (valueObject.isNull() || valueObject.isBoolean()) { + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { continue; } diff --git a/packages/engine-formula/src/functions/statistical/z-test/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/z-test/__tests__/index.spec.ts index 4e0f9abdc36..4e2f3cf313c 100644 --- a/packages/engine-formula/src/functions/statistical/z-test/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/z-test/__tests__/index.spec.ts @@ -44,6 +44,23 @@ describe('Test zTest function', () => { expect(getObjectValue(result)).toBe(0.09057419685136392); }); + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'3', '\'6', '\'7', '\'8', '\'6', '\'5', '\'4', '\'2', '\'1', '\'9'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(4); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toBe(ErrorType.NA); + }); + it('Array value test', () => { const array = ArrayValueObject.create({ calculateValueList: transformToValueObject([ diff --git a/packages/engine-formula/src/functions/statistical/z-test/index.ts b/packages/engine-formula/src/functions/statistical/z-test/index.ts index 6cb89453478..c345864e7b4 100644 --- a/packages/engine-formula/src/functions/statistical/z-test/index.ts +++ b/packages/engine-formula/src/functions/statistical/z-test/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { isRealNum } from '@univerjs/core'; import { ErrorType } from '../../../basics/error-type'; import { normalCDF } from '../../../basics/statistical'; @@ -22,7 +23,6 @@ import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check- import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; export class ZTest extends BaseFunction { override minParams = 2; @@ -150,7 +150,7 @@ export class ZTest extends BaseFunction { return valueObject as ErrorValueObject; } - if (valueObject.isNull() || valueObject.isBoolean()) { + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { continue; }