diff --git a/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php b/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php index 4f15615cb2..af2712053f 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 @@ public static function STDEV(...$args) */ 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 @@ public static function STDEVA(...$args) */ 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 @@ public static function STDEVP(...$args) */ 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 9762ec848f..e53346719c 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 @@ protected static function datatypeAdjustmentAllowStrings($value) 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 78b08da9b1..ac9c33209e 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Variances.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Variances.php @@ -29,6 +29,7 @@ public static function VAR(...$args) $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 @@ public static function VARP(...$args) $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 9115db469d..79e4482a2b 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 @@ public function providerSTDEVA() { 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 9d8921ccde..b004e5b060 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 @@ public function providerSTDEVPA() { 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 47b058b3d2..7e45ec5101 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 @@ public function providerSTDEVP() { 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 6a96fa2f70..bc59869d06 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 @@ public function providerSTDEV() { 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 1b8b676fe2..8d664af4f0 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 @@ public function providerVARA() { 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 ee0cfee601..8240b5cf63 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 @@ public function providerVARPA() { 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 fe3af03746..bbc5239c7d 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 @@ public function providerVARP() { 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 aa25f5cc4b..15aa98a066 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 @@ public function providerVAR() { 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 89713592fb..b2fa9a144a 100644 --- a/tests/data/Calculation/Statistical/AVEDEV.php +++ b/tests/data/Calculation/Statistical/AVEDEV.php @@ -42,4 +42,8 @@ '#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 d435e89bdd..33283cddcd 100644 --- a/tests/data/Calculation/Statistical/AVERAGE.php +++ b/tests/data/Calculation/Statistical/AVERAGE.php @@ -50,4 +50,8 @@ '#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 de6bf1b468..1478155040 100644 --- a/tests/data/Calculation/Statistical/AVERAGEA.php +++ b/tests/data/Calculation/Statistical/AVERAGEA.php @@ -21,4 +21,12 @@ 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 846f8c71b2..30d9dc3b81 100644 --- a/tests/data/Calculation/Statistical/STDEV.php +++ b/tests/data/Calculation/Statistical/STDEV.php @@ -9,4 +9,12 @@ '#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 9fd45d652c..13cecc6171 100644 --- a/tests/data/Calculation/Statistical/STDEVA.php +++ b/tests/data/Calculation/Statistical/STDEVA.php @@ -9,4 +9,12 @@ '#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 0000000000..559798e463 --- /dev/null +++ b/tests/data/Calculation/Statistical/STDEVA_ODS.php @@ -0,0 +1,20 @@ +