From a34dd71cceb9463da37535b2a80fd3ab671ab73f Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 27 Mar 2021 18:31:24 +0100 Subject: [PATCH] Difference in variance calculations between Excel/Gnumeric and Open/LibreOffice (#1959) * Difference in variance calculations between Excel/Gnumeric and Open/LibreOffice * Simplify STDEV() function logic by remembering that STDEV() is simply the square root of VAR(), so we can simply use the VAR() calculaion rather than duplicating the basic logic... and also allow for the differences between Excel/Gnumeric and Open/LibreOffice --- .../Statistical/StandardDeviations.php | 120 +++--------------- .../Calculation/Statistical/VarianceBase.php | 4 +- .../Calculation/Statistical/Variances.php | 2 + .../Functions/Statistical/StDevATest.php | 25 ++++ .../Functions/Statistical/StDevPATest.php | 25 ++++ .../Functions/Statistical/StDevPTest.php | 25 ++++ .../Functions/Statistical/StDevTest.php | 25 ++++ .../Functions/Statistical/VarATest.php | 25 ++++ .../Functions/Statistical/VarPATest.php | 25 ++++ .../Functions/Statistical/VarPTest.php | 25 ++++ .../Functions/Statistical/VarTest.php | 25 ++++ tests/data/Calculation/Statistical/AVEDEV.php | 4 + .../data/Calculation/Statistical/AVERAGE.php | 4 + .../data/Calculation/Statistical/AVERAGEA.php | 8 ++ tests/data/Calculation/Statistical/STDEV.php | 8 ++ tests/data/Calculation/Statistical/STDEVA.php | 8 ++ .../Calculation/Statistical/STDEVA_ODS.php | 20 +++ tests/data/Calculation/Statistical/STDEVP.php | 8 ++ .../data/Calculation/Statistical/STDEVPA.php | 8 ++ .../Calculation/Statistical/STDEVPA_ODS.php | 20 +++ .../Calculation/Statistical/STDEVP_ODS.php | 20 +++ .../Calculation/Statistical/STDEV_ODS.php | 20 +++ tests/data/Calculation/Statistical/VAR.php | 8 ++ tests/data/Calculation/Statistical/VARA.php | 8 ++ .../data/Calculation/Statistical/VARA_ODS.php | 16 +++ tests/data/Calculation/Statistical/VARP.php | 8 ++ tests/data/Calculation/Statistical/VARPA.php | 8 ++ .../Calculation/Statistical/VARPA_ODS.php | 16 +++ .../data/Calculation/Statistical/VARP_ODS.php | 16 +++ .../data/Calculation/Statistical/VAR_ODS.php | 16 +++ 30 files changed, 446 insertions(+), 104 deletions(-) create mode 100644 tests/data/Calculation/Statistical/STDEVA_ODS.php create mode 100644 tests/data/Calculation/Statistical/STDEVPA_ODS.php create mode 100644 tests/data/Calculation/Statistical/STDEVP_ODS.php create mode 100644 tests/data/Calculation/Statistical/STDEV_ODS.php create mode 100644 tests/data/Calculation/Statistical/VARA_ODS.php create mode 100644 tests/data/Calculation/Statistical/VARPA_ODS.php create mode 100644 tests/data/Calculation/Statistical/VARP_ODS.php create mode 100644 tests/data/Calculation/Statistical/VAR_ODS.php diff --git a/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php b/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php index 4f15615c..af271205 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php @@ -2,9 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; - -class StandardDeviations extends VarianceBase +class StandardDeviations { /** * STDEV. @@ -21,34 +19,12 @@ class StandardDeviations extends VarianceBase */ public static function STDEV(...$args) { - $aArgs = Functions::flattenArrayIndexed($args); - - $aMean = Averages::average($aArgs); - - if (!is_string($aMean)) { - $returnValue = 0.0; - $aCount = -1; - - foreach ($aArgs as $k => $arg) { - if ( - (is_bool($arg)) && - ((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE)) - ) { - $arg = (int) $arg; - } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue += ($arg - $aMean) ** 2; - ++$aCount; - } - } - - if ($aCount > 0) { - return sqrt($returnValue / $aCount); - } + $result = Variances::VAR(...$args); + if (!is_numeric($result)) { + return $result; } - return Functions::DIV0(); + return sqrt((float) $result); } /** @@ -65,32 +41,12 @@ class StandardDeviations extends VarianceBase */ public static function STDEVA(...$args) { - $aArgs = Functions::flattenArrayIndexed($args); - - $aMean = Averages::averageA($aArgs); - - if (!is_string($aMean)) { - $returnValue = 0.0; - $aCount = -1; - - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) { - } else { - // Is it a numeric value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { - $arg = self::datatypeAdjustmentAllowStrings($arg); - $returnValue += ($arg - $aMean) ** 2; - ++$aCount; - } - } - } - - if ($aCount > 0) { - return sqrt($returnValue / $aCount); - } + $result = Variances::VARA(...$args); + if (!is_numeric($result)) { + return $result; } - return Functions::DIV0(); + return sqrt((float) $result); } /** @@ -107,34 +63,12 @@ class StandardDeviations extends VarianceBase */ public static function STDEVP(...$args) { - $aArgs = Functions::flattenArrayIndexed($args); - - $aMean = Averages::average($aArgs); - - if (!is_string($aMean)) { - $returnValue = 0.0; - $aCount = 0; - - foreach ($aArgs as $k => $arg) { - if ( - (is_bool($arg)) && - ((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE)) - ) { - $arg = (int) $arg; - } - // Is it a numeric value? - if ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue += ($arg - $aMean) ** 2; - ++$aCount; - } - } - - if ($aCount > 0) { - return sqrt($returnValue / $aCount); - } + $result = Variances::VARP(...$args); + if (!is_numeric($result)) { + return $result; } - return Functions::DIV0(); + return sqrt((float) $result); } /** @@ -151,31 +85,11 @@ class StandardDeviations extends VarianceBase */ public static function STDEVPA(...$args) { - $aArgs = Functions::flattenArrayIndexed($args); - - $aMean = Averages::averageA($aArgs); - - if (!is_string($aMean)) { - $returnValue = 0.0; - $aCount = 0; - - foreach ($aArgs as $k => $arg) { - if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) { - } else { - // Is it a numeric value? - if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { - $arg = self::datatypeAdjustmentAllowStrings($arg); - $returnValue += ($arg - $aMean) ** 2; - ++$aCount; - } - } - } - - if ($aCount > 0) { - return sqrt($returnValue / $aCount); - } + $result = Variances::VARPA(...$args); + if (!is_numeric($result)) { + return $result; } - return Functions::DIV0(); + return sqrt((float) $result); } } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php b/src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php index 9762ec84..e5334671 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; + abstract class VarianceBase { protected static function datatypeAdjustmentAllowStrings($value) @@ -17,7 +19,7 @@ abstract class VarianceBase protected static function datatypeAdjustmentBooleans($value) { - if (is_bool($value)) { + if (is_bool($value) && (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE)) { return (int) $value; } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Variances.php b/src/PhpSpreadsheet/Calculation/Statistical/Variances.php index 78b08da9..ac9c3320 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Variances.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Variances.php @@ -29,6 +29,7 @@ class Variances extends VarianceBase $aCount = 0; foreach ($aArgs as $arg) { $arg = self::datatypeAdjustmentBooleans($arg); + // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { $summerA += ($arg * $arg); @@ -117,6 +118,7 @@ class Variances extends VarianceBase $aCount = 0; foreach ($aArgs as $arg) { $arg = self::datatypeAdjustmentBooleans($arg); + // Is it a numeric value? if ((is_numeric($arg)) && (!is_string($arg))) { $summerA += ($arg * $arg); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php index 9115db46..79e4482a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php @@ -2,11 +2,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; class StDevATest extends TestCase { + protected function tearDown(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + /** * @dataProvider providerSTDEVA * @@ -23,4 +29,23 @@ class StDevATest extends TestCase { return require 'tests/data/Calculation/Statistical/STDEVA.php'; } + + /** + * @dataProvider providerOdsSTDEVA + * + * @param mixed $expectedResult + * @param mixed $values + */ + public function testOdsSTDEVA($expectedResult, $values): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + + $result = Statistical::STDEVA($values); + self::assertEqualsWithDelta($expectedResult, $result, 1E-12); + } + + public function providerOdsSTDEVA() + { + return require 'tests/data/Calculation/Statistical/STDEVA_ODS.php'; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php index 9d8921cc..b004e5b0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php @@ -2,11 +2,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; class StDevPATest extends TestCase { + protected function tearDown(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + /** * @dataProvider providerSTDEVPA * @@ -23,4 +29,23 @@ class StDevPATest extends TestCase { return require 'tests/data/Calculation/Statistical/STDEVPA.php'; } + + /** + * @dataProvider providerOdsSTDEVPA + * + * @param mixed $expectedResult + * @param mixed $values + */ + public function testOdsSTDEVPA($expectedResult, $values): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + + $result = Statistical::STDEVPA($values); + self::assertEqualsWithDelta($expectedResult, $result, 1E-12); + } + + public function providerOdsSTDEVPA() + { + return require 'tests/data/Calculation/Statistical/STDEVPA_ODS.php'; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php index 47b058b3..7e45ec51 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php @@ -2,11 +2,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; class StDevPTest extends TestCase { + protected function tearDown(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + /** * @dataProvider providerSTDEVP * @@ -23,4 +29,23 @@ class StDevPTest extends TestCase { return require 'tests/data/Calculation/Statistical/STDEVP.php'; } + + /** + * @dataProvider providerOdsSTDEVP + * + * @param mixed $expectedResult + * @param mixed $values + */ + public function testOdsSTDEVP($expectedResult, $values): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + + $result = Statistical::STDEVP($values); + self::assertEqualsWithDelta($expectedResult, $result, 1E-12); + } + + public function providerOdsSTDEVP() + { + return require 'tests/data/Calculation/Statistical/STDEVP_ODS.php'; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php index 6a96fa2f..bc59869d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php @@ -2,11 +2,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; class StDevTest extends TestCase { + protected function tearDown(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + /** * @dataProvider providerSTDEV * @@ -23,4 +29,23 @@ class StDevTest extends TestCase { return require 'tests/data/Calculation/Statistical/STDEV.php'; } + + /** + * @dataProvider providerOdsSTDEV + * + * @param mixed $expectedResult + * @param mixed $values + */ + public function testOdsSTDEV($expectedResult, $values): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + + $result = Statistical::STDEV($values); + self::assertEqualsWithDelta($expectedResult, $result, 1E-12); + } + + public function providerOdsSTDEV() + { + return require 'tests/data/Calculation/Statistical/STDEV_ODS.php'; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php index 1b8b676f..8d664af4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php @@ -2,11 +2,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; class VarATest extends TestCase { + protected function tearDown(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + /** * @dataProvider providerVARA * @@ -23,4 +29,23 @@ class VarATest extends TestCase { return require 'tests/data/Calculation/Statistical/VARA.php'; } + + /** + * @dataProvider providerOdsVARA + * + * @param mixed $expectedResult + * @param mixed $values + */ + public function testOdsVARA($expectedResult, $values): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + + $result = Statistical::VARA($values); + self::assertEqualsWithDelta($expectedResult, $result, 1E-12); + } + + public function providerOdsVARA() + { + return require 'tests/data/Calculation/Statistical/VARA_ODS.php'; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php index ee0cfee6..8240b5cf 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php @@ -2,11 +2,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; class VarPATest extends TestCase { + protected function tearDown(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + /** * @dataProvider providerVARPA * @@ -23,4 +29,23 @@ class VarPATest extends TestCase { return require 'tests/data/Calculation/Statistical/VARPA.php'; } + + /** + * @dataProvider providerOdsVARPA + * + * @param mixed $expectedResult + * @param mixed $values + */ + public function testOdsVARPA($expectedResult, $values): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + + $result = Statistical::VARPA($values); + self::assertEqualsWithDelta($expectedResult, $result, 1E-12); + } + + public function providerOdsVARPA() + { + return require 'tests/data/Calculation/Statistical/VARPA_ODS.php'; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php index fe3af037..bbc5239c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php @@ -2,11 +2,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; class VarPTest extends TestCase { + protected function tearDown(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + /** * @dataProvider providerVARP * @@ -23,4 +29,23 @@ class VarPTest extends TestCase { return require 'tests/data/Calculation/Statistical/VARP.php'; } + + /** + * @dataProvider providerOdsVARP + * + * @param mixed $expectedResult + * @param mixed $values + */ + public function testOdsVARP($expectedResult, $values): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + + $result = Statistical::VARP($values); + self::assertEqualsWithDelta($expectedResult, $result, 1E-12); + } + + public function providerOdsVARP() + { + return require 'tests/data/Calculation/Statistical/VARP_ODS.php'; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php index aa25f5cc..15aa98a0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php @@ -2,11 +2,17 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; class VarTest extends TestCase { + protected function tearDown(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + /** * @dataProvider providerVAR * @@ -23,4 +29,23 @@ class VarTest extends TestCase { return require 'tests/data/Calculation/Statistical/VAR.php'; } + + /** + * @dataProvider providerOdsVAR + * + * @param mixed $expectedResult + * @param mixed $values + */ + public function testOdsVAR($expectedResult, $values): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + + $result = Statistical::VARFunc($values); + self::assertEqualsWithDelta($expectedResult, $result, 1E-12); + } + + public function providerOdsVAR() + { + return require 'tests/data/Calculation/Statistical/VAR_ODS.php'; + } } diff --git a/tests/data/Calculation/Statistical/AVEDEV.php b/tests/data/Calculation/Statistical/AVEDEV.php index 89713592..b2fa9a14 100644 --- a/tests/data/Calculation/Statistical/AVEDEV.php +++ b/tests/data/Calculation/Statistical/AVEDEV.php @@ -42,4 +42,8 @@ return [ '#VALUE!', [1, '2', 3.4, true, 5, null, 6.7, 'STRING', ''], ], + [ + '#NUM!', + [], + ], ]; diff --git a/tests/data/Calculation/Statistical/AVERAGE.php b/tests/data/Calculation/Statistical/AVERAGE.php index d435e89b..33283cdd 100644 --- a/tests/data/Calculation/Statistical/AVERAGE.php +++ b/tests/data/Calculation/Statistical/AVERAGE.php @@ -50,4 +50,8 @@ return [ '#VALUE!', [1, '2', 3.4, true, 5, null, 6.7, 'STRING', ''], ], + [ + '#DIV/0!', + [], + ], ]; diff --git a/tests/data/Calculation/Statistical/AVERAGEA.php b/tests/data/Calculation/Statistical/AVERAGEA.php index de6bf1b4..14781550 100644 --- a/tests/data/Calculation/Statistical/AVERAGEA.php +++ b/tests/data/Calculation/Statistical/AVERAGEA.php @@ -21,4 +21,12 @@ return [ 0.5, [true, false], ], + [ + 0.666666666667, + [true, false, 1], + ], + [ + '#DIV/0!', + [], + ], ]; diff --git a/tests/data/Calculation/Statistical/STDEV.php b/tests/data/Calculation/Statistical/STDEV.php index 846f8c71..30d9dc3b 100644 --- a/tests/data/Calculation/Statistical/STDEV.php +++ b/tests/data/Calculation/Statistical/STDEV.php @@ -9,4 +9,12 @@ return [ '#DIV/0!', ['A', 'B', 'C'], ], + [ + '#DIV/0!', + [true, false], + ], + [ + '#DIV/0!', + [true, false, 1], + ], ]; diff --git a/tests/data/Calculation/Statistical/STDEVA.php b/tests/data/Calculation/Statistical/STDEVA.php index 9fd45d65..13cecc61 100644 --- a/tests/data/Calculation/Statistical/STDEVA.php +++ b/tests/data/Calculation/Statistical/STDEVA.php @@ -9,4 +9,12 @@ return [ '#DIV/0!', [], ], + [ + 0.707106781187, + [true, false], + ], + [ + 0.577350269190, + [true, false, 1], + ], ]; diff --git a/tests/data/Calculation/Statistical/STDEVA_ODS.php b/tests/data/Calculation/Statistical/STDEVA_ODS.php new file mode 100644 index 00000000..559798e4 --- /dev/null +++ b/tests/data/Calculation/Statistical/STDEVA_ODS.php @@ -0,0 +1,20 @@ +