mirror of
https://github.com/ONLYOFFICE/sdkjs.git
synced 2026-04-07 14:09:12 +08:00
[se] Added fix for HYPGEOM_DIST function (#1729)
[se] Added fix for HYPGEOM_DIST function Co-authored-by: Dmitriy Orlov <dmitriy.orlov@onlyoffice.com> Co-committed-by: Dmitriy Orlov <dmitriy.orlov@onlyoffice.com>
This commit is contained in:
committed by
Igor Zotov
parent
64c8a6d180
commit
79ddd0784a
@ -85,6 +85,38 @@ function (window, undefined) {
|
||||
cT_DIST_2T, cT_DIST_RT, cT_INV, cT_INV_2T, cTINV, cTREND, cTRIMMEAN, cTTEST, cT_TEST, cVAR, cVARA, cVARP,
|
||||
cVAR_P, cVAR_S, cVARPA, cWEIBULL, cWEIBULL_DIST, cZTEST, cZ_TEST);
|
||||
|
||||
const MAX_SIGNED_INTEGER = 2147483647; // 32 bit
|
||||
|
||||
function hypgeomDistExcel(k, n, M, N, cumulative) {
|
||||
function logC(a, b) {
|
||||
if (b < 0 || b > a) return -Infinity;
|
||||
return getLogGamma(a + 1) - getLogGamma(b + 1) - getLogGamma(a - b + 1);
|
||||
}
|
||||
|
||||
function pmf(x) {
|
||||
return Math.exp(logC(M, x) + logC(N - M, n - x) - logC(N, n));
|
||||
}
|
||||
|
||||
const xmin = Math.max(0, n - (N - M));
|
||||
const xmax = Math.min(n, M);
|
||||
|
||||
// if (cumulative === "FALSE") return pmf(k);
|
||||
if (!cumulative) {
|
||||
if (k < xmin || k > xmax) return 0;
|
||||
return pmf(k);
|
||||
}
|
||||
|
||||
// CDF
|
||||
if (k < xmin) return 0;
|
||||
if (k >= xmax) return 1;
|
||||
|
||||
let sum = 0;
|
||||
for (let x = xmin; x <= k; x++) {
|
||||
sum += pmf(x);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
function integralPhi(x) { // Using gauss(x)+0.5 has severe cancellation errors for x<-4
|
||||
return 0.5 * AscCommonExcel.rtl_math_erfc(-x * 0.7071067811865475); // * 1/sqrt(2)
|
||||
}
|
||||
@ -7281,29 +7313,29 @@ function (window, undefined) {
|
||||
cHYPGEOMDIST.prototype.argumentsMax = 4;
|
||||
cHYPGEOMDIST.prototype.argumentsType = [argType.number, argType.number, argType.number, argType.number];
|
||||
cHYPGEOMDIST.prototype.Calculate = function (arg) {
|
||||
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2], arg3 = arg[3];
|
||||
let arg0 = arg[0], arg1 = arg[1], arg2 = arg[2], arg3 = arg[3];
|
||||
|
||||
if (arg0 instanceof cArea || arg0 instanceof cArea3D) {
|
||||
if (arg0.type === cElementType.cellsRange || arg0.type === cElementType.cellsRange3D) {
|
||||
arg0 = arg0.cross(arguments[1]);
|
||||
} else if (arg0 instanceof cArray) {
|
||||
} else if (arg0.type === cElementType.array) {
|
||||
arg0 = arg0.getElement(0);
|
||||
}
|
||||
|
||||
if (arg1 instanceof cArea || arg1 instanceof cArea3D) {
|
||||
if (arg1.type === cElementType.cellsRange || arg1.type === cElementType.cellsRange3D) {
|
||||
arg1 = arg1.cross(arguments[1]);
|
||||
} else if (arg1 instanceof cArray) {
|
||||
} else if (arg1.type === cElementType.array) {
|
||||
arg1 = arg1.getElement(0);
|
||||
}
|
||||
|
||||
if (arg2 instanceof cArea || arg2 instanceof cArea3D) {
|
||||
if (arg2.type === cElementType.cellsRange || arg2.type === cElementType.cellsRange3D) {
|
||||
arg2 = arg2.cross(arguments[1]);
|
||||
} else if (arg2 instanceof cArray) {
|
||||
} else if (arg2.type === cElementType.array) {
|
||||
arg2 = arg2.getElement(0);
|
||||
}
|
||||
|
||||
if (arg3 instanceof cArea || arg3 instanceof cArea3D) {
|
||||
if (arg3.type === cElementType.cellsRange || arg3.type === cElementType.cellsRange3D) {
|
||||
arg3 = arg3.cross(arguments[1]);
|
||||
} else if (arg3 instanceof cArray) {
|
||||
} else if (arg3.type === cElementType.array) {
|
||||
arg3 = arg3.getElement(0);
|
||||
}
|
||||
|
||||
@ -7312,30 +7344,36 @@ function (window, undefined) {
|
||||
arg2 = arg2.tocNumber();
|
||||
arg3 = arg3.tocNumber();
|
||||
|
||||
if (arg0 instanceof cError) {
|
||||
if (arg0.type === cElementType.error) {
|
||||
return arg0;
|
||||
}
|
||||
if (arg1 instanceof cError) {
|
||||
if (arg1.type === cElementType.error) {
|
||||
return arg1;
|
||||
}
|
||||
if (arg2 instanceof cError) {
|
||||
if (arg2.type === cElementType.error) {
|
||||
return arg2;
|
||||
}
|
||||
if (arg3 instanceof cError) {
|
||||
if (arg3.type === cElementType.error) {
|
||||
return arg3;
|
||||
}
|
||||
|
||||
|
||||
if (arg0.getValue() < 0 || arg0.getValue() > Math.min(arg1.getValue(), arg2.getValue()) ||
|
||||
arg0.getValue() < Math.max(0, arg1.getValue() - arg3.getValue() + arg2.getValue()) ||
|
||||
arg1.getValue() <= 0 || arg1.getValue() > arg3.getValue() || arg2.getValue() <= 0 ||
|
||||
arg2.getValue() > arg3.getValue() || arg3.getValue() <= 0) {
|
||||
arg0 = Math.floor(arg0);
|
||||
arg1 = Math.floor(arg1);
|
||||
arg2 = Math.floor(arg2);
|
||||
arg3 = Math.floor(arg3);
|
||||
|
||||
if (arg0 < 0 || arg1 < 0 || arg2 < 0 || arg3 < 0 || arg1 > arg3 || arg2 > arg3 ) {
|
||||
return new cError(cErrorType.not_numeric);
|
||||
}
|
||||
|
||||
return new cNumber(Math.binomCoeff(arg2.getValue(), arg0.getValue()) *
|
||||
Math.binomCoeff(arg3.getValue() - arg2.getValue(), arg1.getValue() - arg0.getValue()) /
|
||||
Math.binomCoeff(arg3.getValue(), arg1.getValue()));
|
||||
if (arg0 > MAX_SIGNED_INTEGER || arg1 > MAX_SIGNED_INTEGER || arg2 > MAX_SIGNED_INTEGER || arg3 > MAX_SIGNED_INTEGER) {
|
||||
return new cError(cErrorType.not_numeric);
|
||||
}
|
||||
|
||||
let res = hypgeomDistExcel(arg0, arg1, arg2, arg3, /*bCumulative*/ false);
|
||||
|
||||
return isNaN(res) ? new cError(cErrorType.not_numeric) : new cNumber(res);
|
||||
|
||||
};
|
||||
|
||||
@ -7355,54 +7393,47 @@ function (window, undefined) {
|
||||
cHYPGEOM_DIST.prototype.isXLFN = true;
|
||||
cHYPGEOM_DIST.prototype.argumentsType = [argType.number, argType.number, argType.number, argType.number, argType.logical];
|
||||
cHYPGEOM_DIST.prototype.Calculate = function (arg) {
|
||||
var oArguments = this._prepareArguments(arg, arguments[1], true);
|
||||
var argClone = oArguments.args;
|
||||
|
||||
let oArguments = this._prepareArguments(arg, arguments[1], true);
|
||||
let argClone = oArguments.args;
|
||||
|
||||
argClone[0] = argClone[0].tocNumber();
|
||||
argClone[1] = argClone[1].tocNumber();
|
||||
argClone[2] = argClone[2].tocNumber();
|
||||
argClone[3] = argClone[3].tocNumber();
|
||||
argClone[4] = argClone[4].tocNumber();
|
||||
argClone[4] = argClone[4].tocBool();
|
||||
|
||||
var argError;
|
||||
let argError;
|
||||
if (argError = this._checkErrorArg(argClone)) {
|
||||
return argError;
|
||||
}
|
||||
|
||||
function hypgeomdist(argArray) {
|
||||
var arg0 = Math.floor(argArray[0]);
|
||||
var arg1 = Math.floor(argArray[1]);
|
||||
var arg2 = Math.floor(argArray[2]);
|
||||
var arg3 = Math.floor(argArray[3]);
|
||||
var bCumulative = argArray[4];
|
||||
if (argClone[4].type !== cElementType.bool) {
|
||||
return new cError(cErrorType.wrong_value_type);
|
||||
}
|
||||
argClone[4] = argClone[4].value;
|
||||
|
||||
if (arg0 < 0 || arg0 > Math.min(arg1, arg2) || arg0 < Math.max(0, arg1 - arg3 + arg2) || arg1 <= 0 ||
|
||||
arg1 > arg3 || arg2 <= 0 || arg2 > arg3 || arg3 <= 0) {
|
||||
function hypgeomdist(argArray) {
|
||||
let arg0 = Math.floor(argArray[0]),
|
||||
arg1 = Math.floor(argArray[1]),
|
||||
arg2 = Math.floor(argArray[2]),
|
||||
arg3 = Math.floor(argArray[3]),
|
||||
bCumulative = argArray[4];
|
||||
|
||||
if (arg0 < 0 || arg1 < 0 || arg2 < 0 || arg3 < 0 || arg1 > arg3 || arg2 > arg3 ) {
|
||||
return new cError(cErrorType.not_numeric);
|
||||
}
|
||||
|
||||
var res;
|
||||
if (bCumulative) {
|
||||
var fVal = 0.0;
|
||||
if (arg0 > MAX_SIGNED_INTEGER || arg1 > MAX_SIGNED_INTEGER || arg2 > MAX_SIGNED_INTEGER || arg3 > MAX_SIGNED_INTEGER) {
|
||||
return new cError(cErrorType.not_numeric);
|
||||
}
|
||||
|
||||
//TODO значения неверные для этой ветки! пересчитать
|
||||
for (var i = 0; i <= arg0; i++) {
|
||||
var temp = Math.binomCoeff(arg2, i) * Math.binomCoeff(arg3 - arg2, arg1 - i) /
|
||||
Math.binomCoeff(arg3, arg1);
|
||||
if (!isNaN(temp)) {
|
||||
fVal += temp;
|
||||
}
|
||||
}
|
||||
|
||||
res = fVal;
|
||||
} else {
|
||||
res = Math.binomCoeff(arg2, arg0) * Math.binomCoeff(arg3 - arg2, arg1 - arg0) /
|
||||
Math.binomCoeff(arg3, arg1);
|
||||
}
|
||||
let res = hypgeomDistExcel(arg0, arg1, arg2, arg3, bCumulative);
|
||||
|
||||
return isNaN(res) ? new cError(cErrorType.not_numeric) : new cNumber(res);
|
||||
}
|
||||
|
||||
|
||||
return this._findArrayInNumberArguments(oArguments, hypgeomdist);
|
||||
};
|
||||
|
||||
|
||||
@ -20406,11 +20406,7 @@ $(function () {
|
||||
|
||||
oParser = new parserFormula("HYPGEOMDIST(1,4,8,20)", "A1", ws);
|
||||
assert.ok(oParser.parse());
|
||||
assert.strictEqual(oParser.calculate().getValue(), hypgeomdist(1, 4, 8, 20));
|
||||
|
||||
oParser = new parserFormula("HYPGEOMDIST(1,4,8,20)", "A1", ws);
|
||||
assert.ok(oParser.parse());
|
||||
assert.strictEqual(oParser.calculate().getValue(), hypgeomdist(1, 4, 8, 20));
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3632610939112495);
|
||||
|
||||
oParser = new parserFormula("HYPGEOMDIST(-1,4,8,20)", "A1", ws);
|
||||
assert.ok(oParser.parse());
|
||||
@ -20418,7 +20414,7 @@ $(function () {
|
||||
|
||||
oParser = new parserFormula("HYPGEOMDIST(5,4,8,20)", "A1", ws);
|
||||
assert.ok(oParser.parse());
|
||||
assert.strictEqual(oParser.calculate().getValue(), "#NUM!");
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0);
|
||||
|
||||
ws.getRange2("A1:C214").cleanAll();
|
||||
// Data for reference link. Use A100-A111
|
||||
@ -20461,19 +20457,19 @@ $(function () {
|
||||
// Case #1: Number(4). All arguments are integers. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(2,10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(2,10,5,20) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: Number(4). All arguments are integers. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: Number(4). All arguments are integers. 4 of 4 arguments used.');
|
||||
// Case #2: Number(4). All arguments are integers, different valid values. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(1,5,3,15)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(1,5,3,15) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.4945054945054945, 'Test: Positive case: Number(4). All arguments are integers, different valid values. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.4945054945054937, 'Test: Positive case: Number(4). All arguments are integers, different valid values. 4 of 4 arguments used.');
|
||||
// Case #3: String(4). All arguments as strings convertible to valid numbers. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST("2","10","5","20")', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST("2","10","5","20") is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: String(4). All arguments as strings convertible to valid numbers. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: String(4). All arguments as strings convertible to valid numbers. 4 of 4 arguments used.');
|
||||
// Case #4: Formula(4). All arguments filled with formulas resolving to valid values. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(ABS(-2),SUM(5,5),MIN(10,5),MAX(10,20))', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(ABS(-2),SUM(5,5),MIN(10,5),MAX(10,20)) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: Formula(4). All arguments filled with formulas resolving to valid values. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: Formula(4). All arguments filled with formulas resolving to valid values. 4 of 4 arguments used.');
|
||||
// Case #5: Reference link(4). All arguments as cell references to valid values. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(A100,A101,A102,A103)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(A100,A101,A102,A103) is parsed.');
|
||||
@ -20485,7 +20481,7 @@ $(function () {
|
||||
// Case #7: Array(4). All arguments as single-element arrays. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST({2},{10},{5},{20})', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST({2},{10},{5},{20}) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: Array(4). All arguments as single-element arrays. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: Array(4). All arguments as single-element arrays. 4 of 4 arguments used.');
|
||||
// Case #8: Name(4). All arguments as named ranges with valid values. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(TestName,TestName1,TestName2,TestName2)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(TestName,TestName1,TestName2,TestName2) is parsed.');
|
||||
@ -20509,35 +20505,35 @@ $(function () {
|
||||
// Case #13: Formula,Number(3). sample_s filled with IF formula. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(IF(TRUE,2,1),10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(IF(TRUE,2,1),10,5,20) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: Formula,Number(3). sample_s filled with IF formula. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: Formula,Number(3). sample_s filled with IF formula. 4 of 4 arguments used.');
|
||||
// Case #14: Date(4). Date arguments truncated to integers. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(DATE(2025,1,1),DATE(2025,2,1),DATE(2025,3,1),DATE(2025,4,1))', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(DATE(2025,1,1),DATE(2025,2,1),DATE(2025,3,1),DATE(2025,4,1)) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0.960771353, 'Test: Positive case: Date(4). Date arguments truncated to integers. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.9607713533224601, 'Test: Positive case: Date(4). Date arguments truncated to integers. 4 of 4 arguments used.');
|
||||
// Case #15: Time(4). Time arguments adjusted to valid integers. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(TIME(1,0,0)+2,TIME(2,0,0)+10,TIME(3,0,0)+5,TIME(4,0,0)+20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(TIME(1,0,0)+2,TIME(2,0,0)+10,TIME(3,0,0)+5,TIME(4,0,0)+20) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: Time(4). Time arguments adjusted to valid integers. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: Time(4). Time arguments adjusted to valid integers. 4 of 4 arguments used.');
|
||||
// Case #16: Formula,Number(3). HYPGEOMDIST inside SUM formula. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('SUM(HYPGEOMDIST(2,10,5,20),0.1)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: SUM(HYPGEOMDIST(2,10,5,20),0.1) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), '#NUM!', 'Test: Positive case: Formula,Number(3). HYPGEOMDIST inside SUM formula. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.44829721362229036, 'Test: Positive case: Formula,Number(3). HYPGEOMDIST inside SUM formula. 4 of 4 arguments used.');
|
||||
// Case #17: String(3),Number. Numeric strings converted to numbers. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST("2","10","5",20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST("2","10","5",20) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: String(3),Number. Numeric strings converted to numbers. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: String(3),Number. Numeric strings converted to numbers. 4 of 4 arguments used.');
|
||||
// Case #18: Array(4). Multi-element arrays with valid values. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST({2,3},{10,15},{5,7},{20,25})', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST({2,3},{10,15},{5,7},{20,25}) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: Array(4). Multi-element arrays with valid values. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: Array(4). Multi-element arrays with valid values. 4 of 4 arguments used.');
|
||||
// Case #19: Number(4). All arguments as floats, truncated to integers. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(2.7,10.8,5.6,20.4)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(2.7,10.8,5.6,20.4) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: Number(4). All arguments as floats, truncated to integers. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: Number(4). All arguments as floats, truncated to integers. 4 of 4 arguments used.');
|
||||
// Case #20: Number(4). Minimum valid integers for all arguments. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(0,1,0,1)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(0,1,0,1) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Positive case: Number(4). Minimum valid integers for all arguments. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Positive case: Number(4). Minimum valid integers for all arguments. 4 of 4 arguments used.');
|
||||
|
||||
// Negative cases:
|
||||
// Case #1: Number(4). sample_s < 0 returns #NUM!. 4 of 4 arguments used.
|
||||
@ -20559,11 +20555,11 @@ $(function () {
|
||||
// Case #5: Number(4). sample_s > number_sample returns #NUM!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(11,10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(11,10,5,20) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number(4). sample_s > number_sample returns #NUM!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number(4). sample_s > number_sample returns #NUM!. 4 of 4 arguments used.');
|
||||
// Case #6: Number(4). sample_s > population_s returns #NUM!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(6,10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(6,10,5,20) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number(4). sample_s > population_s returns #NUM!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number(4). sample_s > population_s returns #NUM!. 4 of 4 arguments used.');
|
||||
// Case #7: Number(4). number_sample > number_pop returns #NUM!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(6,10,5,4)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(6,10,5,4) is parsed.');
|
||||
@ -20575,7 +20571,7 @@ $(function () {
|
||||
// Case #9: Number(4). sample_s < (number_sample - number_pop + population_s) returns #NUM!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(8,10,2,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(8,10,2,20) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number(4). sample_s < (number_sample - number_pop + population_s) returns #NUM!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number(4). sample_s < (number_sample - number_pop + population_s) returns #NUM!. 4 of 4 arguments used.');
|
||||
// Case #10: String(4). Non-numeric string returns #VALUE!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST("abc","10","5","20")', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST("abc","10","5","20") is parsed.');
|
||||
@ -20583,15 +20579,15 @@ $(function () {
|
||||
// Case #11: Empty,Number(3). sample_s empty returns #VALUE!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(,10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(,10,5,20) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040248, 'Test: Negative case: Empty,Number(3). sample_s empty returns #VALUE!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040196, 'Test: Negative case: Empty,Number(3). sample_s empty returns #VALUE!. 4 of 4 arguments used.');
|
||||
// Case #12: Number,Empty,Number(2). number_sample empty returns #VALUE!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(2,,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(2,,5,20) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number,Empty,Number(2). number_sample empty returns #VALUE!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number,Empty,Number(2). number_sample empty returns #VALUE!. 4 of 4 arguments used.');
|
||||
// Case #13: Number(2),Empty,Number. population_s empty returns #VALUE!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(2,10,,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(2,10,,20) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number(2),Empty,Number. population_s empty returns #VALUE!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0, 'Test: Negative case: Number(2),Empty,Number. population_s empty returns #VALUE!. 4 of 4 arguments used.');
|
||||
// Case #14: Number(3),Empty. number_pop empty returns #VALUE!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(2,10,5,)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(2,10,5,) is parsed.');
|
||||
@ -20602,20 +20598,21 @@ $(function () {
|
||||
assert.strictEqual(oParser.calculate().getValue(), '#N/A', 'Test: Negative case: Error,Number(3). sample_s as error propagates #N/A. 4 of 4 arguments used.');
|
||||
// Case #16: Area,Number(3). sample_s as multi-cell range returns #NUM!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(A100:A101,10,5,20)', 'A2', ws);
|
||||
oParser.setArrayFormulaRef(ws.getRange2("B1:C2").bbox);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(A100:A101,10,5,20) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0.01625387, 'Test: Negative case: Area,Number(3). sample_s as multi-cell range returns #NUM!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getElementRowCol(0,0).getValue().toFixed(8) - 0, 0.01625387, 'Test: Negative case: Area,Number(3). sample_s as multi-cell range returns #NUM!. 4 of 4 arguments used.');
|
||||
// Case #17: Array,Number(3). sample_s as multi-element array returns #NUM!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST({2,3},10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST({2,3},10,5,20) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Negative case: Array,Number(3). sample_s as multi-element array returns #NUM!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Negative case: Array,Number(3). sample_s as multi-element array returns #NUM!. 4 of 4 arguments used.');
|
||||
// Case #18: Name,Number(3). sample_s as named range with area returns #VALUE!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(TestNameArea2,10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(TestNameArea2,10,5,20) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.8126934984520123, 'Test: Negative case: Name,Number(3). sample_s as named range with area returns #VALUE!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040196, 'Test: Negative case: Name,Number(3). sample_s as named range with area returns #VALUE!. 4 of 4 arguments used.');
|
||||
// Case #19: Name3D,Number(3). sample_s as 3D named range with area returns #VALUE!. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(TestNameArea3D2,10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(TestNameArea3D2,10,5,20) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.8126934984520123, 'Test: Negative case: Name3D,Number(3). sample_s as 3D named range with area returns #VALUE!. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040196, 'Test: Negative case: Name3D,Number(3). sample_s as 3D named range with area returns #VALUE!. 4 of 4 arguments used.');
|
||||
// Case #20: Formula,Number(3). sample_s as formula resulting in #NUM! propagates error. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(SQRT(-1),10,5,20)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(SQRT(-1),10,5,20) is parsed.');
|
||||
@ -20625,7 +20622,7 @@ $(function () {
|
||||
// Case #1: Number(4). Minimum valid values for sample_s, number_sample, population_s, number_pop. 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(0,1,0,1)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(0,1,0,1) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Bounded case: Number(4). Minimum valid values for sample_s, number_sample, population_s, number_pop. 4 of 4 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Bounded case: Number(4). Minimum valid values for sample_s, number_sample, population_s, number_pop. 4 of 4 arguments used.');
|
||||
// Case #2: Number(4). Maximum valid Excel numbers (truncated to integers). 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(1E+307,1E+307,1E+307,1E+307)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(1E+307,1E+307,1E+307,1E+307) is parsed.');
|
||||
@ -20633,20 +20630,7 @@ $(function () {
|
||||
// Case #3: Number(4). Smallest positive number for sample_s (truncates to 0). 4 of 4 arguments used.
|
||||
oParser = new parserFormula('HYPGEOMDIST(1E-307,2,1,3)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOMDIST(1E-307,2,1,3) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3333333333333333, 'Test: Bounded case: Number(4). Smallest positive number for sample_s (truncates to 0). 4 of 4 arguments used.');
|
||||
|
||||
// Need to fix: ms diff results, boundary cases problem
|
||||
// Case #14: Date(4). Date arguments truncated to integers. 4 of 4 arguments used.
|
||||
// Case #16: Formula,Number(3). HYPGEOMDIST inside SUM formula. 4 of 4 arguments used.
|
||||
// Case #19: Number(4). All arguments as floats, truncated to integers. 4 of 4 arguments used.
|
||||
// Case #20: Number(4). Minimum valid integers for all arguments. 4 of 4 arguments used
|
||||
// Case #5: Number(4). sample_s > number_sample returns #NUM!. 4 of 4 arguments used.
|
||||
// Case #6: Number(4). sample_s > population_s returns #NUM!. 4 of 4 arguments used.
|
||||
// Case #9: Number(4). sample_s < (number_sample - number_pop + population_s) returns #NUM!. 4 of 4 arguments used.
|
||||
// Case #12: Number,Empty,Number(2). number_sample empty returns #VALUE!. 4 of 4 arguments used.
|
||||
// Case #13: Number(2),Empty,Number. population_s empty returns #VALUE!. 4 of 4 arguments used.
|
||||
// Case #16: Area,Number(3). sample_s as multi-cell range returns #NUM!. 4 of 4 arguments used.
|
||||
// Case #1: Number(4). Minimum valid values for sample_s, number_sample, population_s, number_pop. 4 of 4 arguments used.
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.33, 'Test: Bounded case: Number(4). Smallest positive number for sample_s (truncates to 0). 4 of 4 arguments used.');
|
||||
|
||||
|
||||
testArrayFormula2(assert, "HYPGEOMDIST", 4, 4);
|
||||
@ -20672,7 +20656,7 @@ $(function () {
|
||||
|
||||
oParser = new parserFormula("HYPGEOM.DIST(1,2,3,4,5)", "A1", ws);
|
||||
assert.ok(oParser.parse());
|
||||
assert.strictEqual(oParser.calculate().getValue() - 0, 0.5);
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5);
|
||||
|
||||
ws.getRange2("A1:C214").cleanAll();
|
||||
// Data for reference link. Use A100-A111
|
||||
@ -20714,23 +20698,23 @@ $(function () {
|
||||
// Case #1: Number(5). All arguments are integers, cumulative TRUE. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(2,10,5,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(2,10,5,20,TRUE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: Number(5). All arguments are integers, cumulative TRUE. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: Number(5). All arguments are integers, cumulative TRUE. 5 of 5 arguments used.');
|
||||
// Case #2: Number(5). All arguments are integers, cumulative FALSE. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(2,10,5,20,FALSE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(2,10,5,20,FALSE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.34829721362229105, 'Test: Positive case: Number(5). All arguments are integers, cumulative FALSE. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3482972136222904, 'Test: Positive case: Number(5). All arguments are integers, cumulative FALSE. 5 of 5 arguments used.');
|
||||
// Case #3: Number(4),Boolean. Cumulative as numeric 1 (converts to TRUE). 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(2,10,5,20,1)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(2,10,5,20,1) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: Number(4),Boolean. Cumulative as numeric 1 (converts to TRUE). 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: Number(4),Boolean. Cumulative as numeric 1 (converts to TRUE). 5 of 5 arguments used.');
|
||||
// Case #4: String(5). All arguments as strings convertible to valid numbers/boolean. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST("2","10","5","20","TRUE")', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST("2","10","5","20","TRUE") is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: String(5). All arguments as strings convertible to valid numbers/boolean. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: String(5). All arguments as strings convertible to valid numbers/boolean. 5 of 5 arguments used.');
|
||||
// Case #5: Formula(5). All arguments filled with formulas resolving to valid values. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(ABS(-2),SUM(5,5),MIN(10,5),MAX(10,20),IF(TRUE,1,0))', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(ABS(-2),SUM(5,5),MIN(10,5),MAX(10,20),IF(TRUE,1,0)) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: Formula(5). All arguments filled with formulas resolving to valid values. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: Formula(5). All arguments filled with formulas resolving to valid values. 5 of 5 arguments used.');
|
||||
// Case #6: Reference link(5). All arguments as cell references to valid values. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(A100,A101,A102,A103,A104)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(A100,A101,A102,A103,A104) is parsed.');
|
||||
@ -20742,7 +20726,7 @@ $(function () {
|
||||
// Case #8: Array(5). All arguments as single-element arrays. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST({2},{10},{5},{20},{TRUE})', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST({2},{10},{5},{20},{TRUE}) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: Array(5). All arguments as single-element arrays. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: Array(5). All arguments as single-element arrays. 5 of 5 arguments used.');
|
||||
// Case #9: Name(5). All arguments as named ranges with valid values. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(TestName,TestName1,TestName2,TestName,TestName)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(TestName,TestName1,TestName2,TestName,TestName) is parsed.');
|
||||
@ -20766,31 +20750,31 @@ $(function () {
|
||||
// Case #14: Number(4),Formula. Cumulative filled with IF formula. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(2,10,5,20,IF(TRUE,TRUE,FALSE))', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(2,10,5,20,IF(TRUE,TRUE,FALSE)) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: Number(4),Formula. Cumulative filled with IF formula. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: Number(4),Formula. Cumulative filled with IF formula. 5 of 5 arguments used.');
|
||||
// Case #15: Date(4),Boolean. Date arguments truncated to integers. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(DATE(2025,1,1),DATE(2025,2,1),DATE(2025,3,1),DATE(2025,4,1),TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(DATE(2025,1,1),DATE(2025,2,1),DATE(2025,3,1),DATE(2025,4,1),TRUE) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0.960771353, 'Test: Positive case: Date(4),Boolean. Date arguments truncated to integers. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(9) - 0, 0.960771353, 'Test: Positive case: Date(4),Boolean. Date arguments truncated to integers. 5 of 5 arguments used.');
|
||||
// Case #16: Time(4),Boolean. Time arguments adjusted to valid integers. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(TIME(1,0,0)+1,TIME(2,0,0)+10,TIME(3,0,0)+5,TIME(4,0,0)+20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(TIME(1,0,0)+1,TIME(2,0,0)+10,TIME(3,0,0)+5,TIME(4,0,0)+20,TRUE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.15170278637770898, 'Test: Positive case: Time(4),Boolean. Time arguments adjusted to valid integers. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(9) - 0, 0.151702786, 'Test: Positive case: Time(4),Boolean. Time arguments adjusted to valid integers. 5 of 5 arguments used.');
|
||||
// Case #17: Formula,Number(4). HYPGEOM.DIST inside SUM formula. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('SUM(HYPGEOM.DIST(2,10,5,20,TRUE),0.1)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: SUM(HYPGEOM.DIST(2,10,5,20,TRUE),0.1) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.6, 'Test: Positive case: Formula,Number(4). HYPGEOM.DIST inside SUM formula. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.6, 'Test: Positive case: Formula,Number(4). HYPGEOM.DIST inside SUM formula. 5 of 5 arguments used.');
|
||||
// Case #18: String(4),Number. Numeric strings converted to numbers, cumulative as 1. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST("2","10","5","20",1)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST("2","10","5","20",1) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: String(4),Number. Numeric strings converted to numbers, cumulative as 1. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: String(4),Number. Numeric strings converted to numbers, cumulative as 1. 5 of 5 arguments used.');
|
||||
// Case #19: Array(5). Multi-element arrays with valid values. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST({2,3},{10,15},{5,7},{20,25},{TRUE,FALSE})', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST({2,3},{10,15},{5,7},{20,25},{TRUE,FALSE}) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: Array(5). Multi-element arrays with valid values. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: Array(5). Multi-element arrays with valid values. 5 of 5 arguments used.');
|
||||
// Case #20: Number(5). All arguments as floats, truncated to integers. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(2.7,10.8,5.6,20.4,0.9)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(2.7,10.8,5.6,20.4,0.9) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Positive case: Number(5). All arguments as floats, truncated to integers. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Positive case: Number(5). All arguments as floats, truncated to integers. 5 of 5 arguments used.');
|
||||
|
||||
// Negative cases:
|
||||
// Case #1: Number(5). sample_s < 0 returns #NUM!. 5 of 5 arguments used.
|
||||
@ -20812,11 +20796,11 @@ $(function () {
|
||||
// Case #5: Number(5). sample_s > number_sample returns #NUM!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(11,10,5,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(11,10,5,20,TRUE) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number(5). sample_s > number_sample returns #NUM!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number(5). sample_s > number_sample returns #NUM!. 5 of 5 arguments used.');
|
||||
// Case #6: Number(5). sample_s > population_s returns #NUM!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(6,10,5,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(6,10,5,20,TRUE) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number(5). sample_s > population_s returns #NUM!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number(5). sample_s > population_s returns #NUM!. 5 of 5 arguments used.');
|
||||
// Case #7: Number(5). number_sample > number_pop returns #NUM!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(6,10,5,4,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(6,10,5,4,TRUE) is parsed.');
|
||||
@ -20828,23 +20812,23 @@ $(function () {
|
||||
// Case #9: Number(5). sample_s < (number_sample - number_pop + population_s) returns #NUM!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(8,10,2,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(8,10,2,20,TRUE) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number(5). sample_s < (number_sample - number_pop + population_s) returns #NUM!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number(5). sample_s < (number_sample - number_pop + population_s) returns #NUM!. 5 of 5 arguments used.');
|
||||
// Case #10: String(5). Non-numeric string returns #VALUE!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST("abc","10","5","20","TRUE")', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST("abc","10","5","20","TRUE") is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), '#VALUE!', 'Test: Negative case: String(5). Non-numeric string returns #VALUE!. 5 of 5 arguments used.');
|
||||
// Case #11: Empty,Number(4). sample_s empty returns #VALUE!. 5 of 5 arguments used.
|
||||
// Case #11: Empty,Number(4). sample_s empty returns number. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(,10,5,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(,10,5,20,TRUE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040248, 'Test: Negative case: Empty,Number(4). sample_s empty returns #VALUE!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(9) - 0, 0.01625387, 'Test: Negative case: Empty,Number(4). sample_s empty returns number. 5 of 5 arguments used.');
|
||||
// Case #12: Number,Empty,Number(3). number_sample empty returns #VALUE!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(2,,5,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(2,,5,20,TRUE) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number,Empty,Number(3). number_sample empty returns #VALUE!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number,Empty,Number(3). number_sample empty returns #VALUE!. 5 of 5 arguments used.');
|
||||
// Case #13: Number(2),Empty,Number(2). population_s empty returns #VALUE!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(2,10,,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(2,10,,20,TRUE) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number(2),Empty,Number(2). population_s empty returns #VALUE!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Negative case: Number(2),Empty,Number(2). population_s empty returns #VALUE!. 5 of 5 arguments used.');
|
||||
// Case #14: Number(3),Empty,Boolean. number_pop empty returns #VALUE!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(2,10,5,,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(2,10,5,,TRUE) is parsed.');
|
||||
@ -20859,46 +20843,36 @@ $(function () {
|
||||
assert.strictEqual(oParser.calculate().getValue(), '#N/A', 'Test: Negative case: Error,Number(4). sample_s as error propagates #N/A. 5 of 5 arguments used.');
|
||||
// Case #17: Area,Number(4). sample_s as multi-cell range returns #NUM!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(A100:A101,10,5,20,TRUE)', 'A2', ws);
|
||||
oParser.setArrayFormulaRef(ws.getRange2("B1:C2").bbox);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(A100:A101,10,5,20,TRUE) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 0.01625387, 'Test: Negative case: Area,Number(4). sample_s as multi-cell range returns #NUM!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getElementRowCol(0,0).getValue(), 0.016253869969040196, 'Test: Negative case: Area,Number(4). sample_s as multi-cell range returns #NUM!. 5 of 5 arguments used.');
|
||||
// Case #18: Array,Number(4). sample_s as multi-element array returns #NUM!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST({2,3},10,5,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST({2,3},10,5,20,TRUE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.5, 'Test: Negative case: Array,Number(4). sample_s as multi-element array returns #NUM!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue().toFixed(2) - 0, 0.5, 'Test: Negative case: Array,Number(4). sample_s as multi-element array returns #NUM!. 5 of 5 arguments used.');
|
||||
// Case #19: Name,Number(4). sample_s as named range with area returns #VALUE!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(TestNameArea2,10,5,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(TestNameArea2,10,5,20,TRUE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040248, 'Test: Negative case: Name,Number(4). sample_s as named range with area returns #VALUE!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040196, 'Test: Negative case: Name,Number(4). sample_s as named range with area returns #VALUE!. 5 of 5 arguments used.');
|
||||
// Case #20: Name3D,Number(4). sample_s as 3D named range with area returns #VALUE!. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(TestNameArea3D2,10,5,20,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(TestNameArea3D2,10,5,20,TRUE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040248, 'Test: Negative case: Name3D,Number(4). sample_s as 3D named range with area returns #VALUE!. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.016253869969040196, 'Test: Negative case: Name3D,Number(4). sample_s as 3D named range with area returns #VALUE!. 5 of 5 arguments used.');
|
||||
|
||||
// Bounded cases:
|
||||
// Case #1: Number(5). Minimum valid values for sample_s, number_sample, population_s, number_pop. 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(0,1,0,1,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(0,1,0,1,TRUE) is parsed.');
|
||||
//? assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Bounded case: Number(5). Minimum valid values for sample_s, number_sample, population_s, number_pop. 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 1, 'Test: Bounded case: Number(5). Minimum valid values for sample_s, number_sample, population_s, number_pop. 5 of 5 arguments used.');
|
||||
// Case #2: Number(5). Maximum valid Excel numbers (truncated to integers). 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(1E+307,1E+307,1E+307,1E+307,TRUE)', 'A2', ws);
|
||||
// assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(1E+307,1E+307,1E+307,1E+307,TRUE) is parsed.');
|
||||
//?! assert.strictEqual(oParser.calculate().getValue(), '#NUM!', 'Test: Bounded case: Number(5). Maximum valid Excel numbers (truncated to integers). 5 of 5 arguments used.');
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(1E+307,1E+307,1E+307,1E+307,TRUE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), '#NUM!', 'Test: Bounded case: Number(5). Maximum valid Excel numbers (truncated to integers). 5 of 5 arguments used.');
|
||||
// Case #3: Number(5). Smallest positive number for sample_s (truncates to 0). 5 of 5 arguments used.
|
||||
oParser = new parserFormula('HYPGEOM.DIST(1E-307,2,1,3,TRUE)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: HYPGEOM.DIST(1E-307,2,1,3,TRUE) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.3333333333333333, 'Test: Bounded case: Number(5). Smallest positive number for sample_s (truncates to 0). 5 of 5 arguments used.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), 0.33333333333333337, 'Test: Bounded case: Number(5). Smallest positive number for sample_s (truncates to 0). 5 of 5 arguments used.');
|
||||
|
||||
// Need to fix:
|
||||
// Case #4: String(5). All arguments as strings convertible to valid numbers/boolean. 5 of 5 arguments used.
|
||||
// Case #15: Date(4),Boolean. Date arguments truncated to integers. 5 of 5 arguments used.
|
||||
// Case #5: Number(5). sample_s > number_sample returns #NUM!. 5 of 5 arguments used.
|
||||
// Case #6: Number(5). sample_s > population_s returns #NUM!. 5 of 5 arguments used.
|
||||
// Case #9: Number(5). sample_s < (number_sample - number_pop + population_s) returns #NUM!. 5 of 5 arguments used.
|
||||
// Case #12: Number,Empty,Number(3). number_sample empty returns #VALUE!. 5 of 5 arguments used.
|
||||
// Case #13: Number(2),Empty,Number(2). population_s empty returns #VALUE!. 5 of 5 arguments used.
|
||||
// Case #17: Area,Number(4). sample_s as multi-cell range returns #NUM!. 5 of 5 arguments used.
|
||||
// Case #1: Number(5). Minimum valid values for sample_s, number_sample, population_s, number_pop. 5 of 5 arguments used.
|
||||
// Case #2: Number(5). Maximum valid Excel numbers (truncated to integers). 5 of 5 arguments used. - critical
|
||||
|
||||
|
||||
testArrayFormula2(assert, "HYPGEOM.DIST", 5, 5);
|
||||
@ -34192,7 +34166,7 @@ $(function () {
|
||||
assert.strictEqual(oParser.calculate().getValue(), '#DIV/0!', 'Test: Negative case: String. Empty string in array returns #VALUE!.');
|
||||
// Case #17: Formula. Nested IF returning text causes #DIV/0!.
|
||||
oParser = new parserFormula('SKEW.P(IF(FALSE,1,"text"),2,3)', 'A2', ws);
|
||||
assert.ok(oParser.parse(), 'Test: SKEW.P(IF(FALSE,1,"text"),2,3) is parsed.');debugger
|
||||
assert.ok(oParser.parse(), 'Test: SKEW.P(IF(FALSE,1,"text"),2,3) is parsed.');
|
||||
assert.strictEqual(oParser.calculate().getValue(), '#DIV/0!', 'Test: Negative case: Formula. Nested IF returning text causes #DIV/0!.');
|
||||
// Case #18: Reference link. Reference to error value returns #N/A.
|
||||
oParser = new parserFormula('SKEW.P(A109)', 'A2', ws);
|
||||
|
||||
Reference in New Issue
Block a user