From 1535b4d9e70de194ddbc56ba0274dbef95010383 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 14 Jul 2012 14:20:17 +0100 Subject: [PATCH] Feature: Modified ERF and ERFC Engineering functions to accept Excel 2010's modified acceptance of negative arguments --- Classes/PHPExcel/Calculation/Engineering.php | 66 ++--- changelog.txt | 1 + .../PHPExcel/Calculation/EngineeringTest.php | 4 +- .../Calculation/Engineering/ERF.data | 245 +++++++++--------- .../Calculation/Engineering/ERFC.data | 123 +++------ 5 files changed, 202 insertions(+), 237 deletions(-) diff --git a/Classes/PHPExcel/Calculation/Engineering.php b/Classes/PHPExcel/Calculation/Engineering.php index efae2e24..38782f8f 100644 --- a/Classes/PHPExcel/Calculation/Engineering.php +++ b/Classes/PHPExcel/Calculation/Engineering.php @@ -771,24 +771,25 @@ class PHPExcel_Calculation_Engineering { /** - * BESSELI + * BESSELI * - * Returns the modified Bessel function, which is equivalent to the Bessel function evaluated for - * purely imaginary arguments + * Returns the modified Bessel function, which is equivalent to the Bessel function evaluated for + * purely imaginary arguments * - * Excel Function: + * Excel Function: * BESSELI(x,ord) * - * @access public - * @category Engineering Functions - * @param float $x The value at which to evaluate the function. + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. * If x is nonnumeric, BESSELI returns the #VALUE! error value. - * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. * If $ord is nonnumeric, BESSELI returns the #VALUE! error value. * If $ord < 0, BESSELI returns the #NUM! error value. - * @return float + * @return float * - * @TODO Better handling of the approximation method to support the differences between Excel/Gnumeric and Open/Libre Office + * @TODO Better handling of the approximation method to support the differences between Excel/Gnumeric + * and Open/Libre Office * */ public static function BESSELI($x, $ord) { @@ -2259,33 +2260,32 @@ class PHPExcel_Calculation_Engineering { /** - * ERF + * ERF * - * Returns the error function integrated between lower_limit and upper_limit + * Returns the error function integrated between the lower and upper bound arguments. * - * Excel Function: + * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, + * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was + * improved, so that it can now calculate the function for both positive and negative ranges. + * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. + * + * Excel Function: * ERF(lower[,upper]) * - * @param float $lower lower bound for integrating ERF - * @param float $upper upper bound for integrating ERF. + * @param float $lower lower bound for integrating ERF + * @param float $upper upper bound for integrating ERF. * If omitted, ERF integrates between zero and lower_limit - * @return int + * @return float */ - public static function ERF($lower, $upper = null) { + public static function ERF($lower, $upper = NULL) { $lower = PHPExcel_Calculation_Functions::flattenSingleValue($lower); $upper = PHPExcel_Calculation_Functions::flattenSingleValue($upper); if (is_numeric($lower)) { - if ($lower < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } if (is_null($upper)) { return self::_erfVal($lower); } if (is_numeric($upper)) { - if ($upper < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } return self::_erfVal($upper) - self::_erfVal($lower); } } @@ -2326,23 +2326,25 @@ class PHPExcel_Calculation_Engineering { /** - * ERFC + * ERFC * - * Returns the complementary ERF function integrated between x and infinity + * Returns the complementary ERF function integrated between x and infinity * - * Excel Function: + * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument, + * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was + * improved, so that it can now calculate the function for both positive and negative x values. + * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. + * + * Excel Function: * ERF(x) * - * @param float $x The lower bound for integrating ERF - * @return int + * @param float $x The lower bound for integrating ERF + * @return float */ public static function ERFC($x) { - $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); if (is_numeric($x)) { - if ($x < 0) { - return PHPExcel_Calculation_Functions::NaN(); - } return self::_erfcVal($x); } return PHPExcel_Calculation_Functions::VALUE(); diff --git a/changelog.txt b/changelog.txt index bdfa9644..c10a41c9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -30,6 +30,7 @@ Fixed in develop branch: tcPDF Library has now been removed from the deployment bundle - Feature: (MBaker) Initial version of HTML Reader - Feature: (Progi1984) & (blazzy) Work items 9605 - Implement support for AutoFilter in PHPExcel_Writer_Excel5 +- Feature: (MBaker) Modified ERF and ERFC Engineering functions to accept Excel 2010's modified acceptance of negative arguments - Bugfix: (cyberconte) Patch 12318 - OOCalc cells containing inside the tag - Bugfix: (schir1964) Fix to listWorksheetInfo() method for OOCalc Reader - Bugfix: (MBaker) Support for "e" (epoch) date format mask diff --git a/unitTests/PHPExcel/Calculation/EngineeringTest.php b/unitTests/PHPExcel/Calculation/EngineeringTest.php index 5e33769a..030ccb53 100644 --- a/unitTests/PHPExcel/Calculation/EngineeringTest.php +++ b/unitTests/PHPExcel/Calculation/EngineeringTest.php @@ -405,7 +405,7 @@ class EngineeringTest extends PHPUnit_Framework_TestCase $args = func_get_args(); $expectedResult = array_pop($args); $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERF'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-6); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); } public function providerERF() @@ -421,7 +421,7 @@ class EngineeringTest extends PHPUnit_Framework_TestCase $args = func_get_args(); $expectedResult = array_pop($args); $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERFC'),$args); - $this->assertEquals($expectedResult, $result, NULL, 1E-6); + $this->assertEquals($expectedResult, $result, NULL, 1E-12); } public function providerERFC() diff --git a/unitTests/rawTestData/Calculation/Engineering/ERF.data b/unitTests/rawTestData/Calculation/Engineering/ERF.data index f7888d5a..d52cf32c 100644 --- a/unitTests/rawTestData/Calculation/Engineering/ERF.data +++ b/unitTests/rawTestData/Calculation/Engineering/ERF.data @@ -1,121 +1,124 @@ -0, 0.0 -0.01, 0.0112834155558496 -0.05, 0.0563719777970166 -0.1, 0.1124629160182850 -0.125, 0.1403162048013340 -0.15, 0.1679959714273630 -0.2, 0.2227025892104780 -0.25, 0.2763263901682370 -0.3, 0.3286267594591270 -0.35, 0.3793820535623100 -0.4, 0.4283923550466680 -0.45, 0.4754817197869240 -0.5, 0.5204998778130470 -0.6, 0.6038560908479260 -0.7, 0.6778011938374180 -0.8, 0.7421009647076610 -0.9, 0.7969082124228320 -1, 0.8427007929497150 -1.1, 0.8802050695740820 -1.2, 0.9103139782296350 -1.3, 0.9340079449406520 -1.4, 0.9522851197626490 -1.5, 0.9661051464753110 -1.75, 0.9866716712191820 -2, 0.9953222650189530 -2.5, 0.9995930479825550 -3, 0.9999779095030010 -3.5, 0.9999992569016280 -4, 0.9999999845827420 -4.5, 0.9999999998033840 -5, 0.9999999999984630 -5.5, 0.9999999999999930 -6, 1.0 -32, 1.0 --0.1, -0.1124629160182850 --1, -0.8427007929497150 -TRUE, "#VALUE!" -FALSE, "#VALUE!" -2, 0.9953222650189530 -"TWO", "#VALUE!" --1.5, -1.5, 0 --0.75, -1.5, -0.254949513 -0, -1.5, -0.966105146 -0.75, -1.5, -1.67726078 -1.5, -1.5, -1.932210293 -2.25, -1.5, -1.96464243 -3, -1.5, -1.966083056 -3.75, -1.5, -1.966105033 -4.5, -1.5, -1.966105146 --1.5, -0.75, 0.254949513 --0.75, -0.75, 0 -0, -0.75, -0.711155634 -0.75, -0.75, -1.422311267 -1.5, -0.75, -1.67726078 -2.25, -0.75, -1.709692917 -3, -0.75, -1.711133543 -3.75, -0.75, -1.71115552 -4.5, -0.75, -1.711155633 --1.5, 0, 0.966105146 --0.75, 0, 0.711155634 -0, 0, 0 -0.75, 0, -0.711155634 -1.5, 0, -0.966105146 -2.25, 0, -0.998537283 -3, 0, -0.99997791 -3.75, 0, -0.999999886 -4.5, 0, -1 --1.5, 0.75, 1.67726078 --0.75, 0.75, 1.422311267 -0, 0.75, 0.711155634 -0.75, 0.75, 0 -1.5, 0.75, -0.254949513 -2.25, 0.75, -0.28738165 -3, 0.75, -0.288822276 -3.75, 0.75, -0.288844253 -4.5, 0.75, -0.288844366 --1.5, 1.5, 1.932210293 --0.75, 1.5, 1.67726078 -0, 1.5, 0.966105146 -0.75, 1.5, 0.254949513 -1.5, 1.5, 0 -2.25, 1.5, -0.032432137 -3, 1.5, -0.033872763 -3.75, 1.5, -0.03389474 -4.5, 1.5, -0.033894853 --1.5, 2.25, 1.96464243 --0.75, 2.25, 1.709692917 -0, 2.25, 0.998537283 -0.75, 2.25, 0.28738165 -1.5, 2.25, 0.032432137 -2.25, 2.25, 0 -3, 2.25, -0.001440626 -3.75, 2.25, -0.001462603 -4.5, 2.25, -0.001462716 --1.5, 3, 1.966083056 --0.75, 3, 1.711133543 -0, 3, 0.99997791 -0.75, 3, 0.288822276 -1.5, 3, 0.033872763 -2.25, 3, 0.001440626 -3, 3, 0 -3.75, 3, -2.19768E-05 -4.5, 3, -2.20903E-05 --1.5, 3.75, 1.966105033 --0.75, 3.75, 1.71115552 -0, 3.75, 0.999999886 -0.75, 3.75, 0.288844253 -1.5, 3.75, 0.03389474 -2.25, 3.75, 0.001462603 -3, 3.75, 2.19768E-05 -3.75, 3.75, 0 -4.5, 3.75, -1.13531E-07 --1.5, 4.5, 1.966105146 --0.75, 4.5, 1.711155633 -0, 4.5, 1 -0.75, 4.5, 0.288844366 -1.5, 4.5, 0.033894853 -2.25, 4.5, 0.001462716 -3, 4.5, 2.20903E-05 -3.75, 4.5, 1.13531E-07 -4.5, 4.5, 0 +# lower bound upper bound Result +0, 0.0 +0.01, 0.0112834155558496 +0.05, 0.0563719777970166 +0.1, 0.1124629160182850 +0.125, 0.1403162048013340 +0.15, 0.1679959714273630 +0.2, 0.2227025892104780 +0.25, 0.2763263901682370 +0.3, 0.3286267594591270 +0.35, 0.3793820535623100 +0.4, 0.4283923550466680 +0.45, 0.4754817197869240 +0.5, 0.5204998778130470 +0.6, 0.6038560908479260 +0.7, 0.6778011938374180 +0.8, 0.7421009647076610 +0.9, 0.7969082124228320 +1, 0.8427007929497150 +1.1, 0.8802050695740820 +1.2, 0.9103139782296350 +1.3, 0.9340079449406520 +1.4, 0.9522851197626490 +1.5, 0.9661051464753110 +1.75, 0.9866716712191820 +2, 0.9953222650189530 +2.5, 0.9995930479825550 +3, 0.9999779095030010 +3.5, 0.9999992569016280 +4, 0.9999999845827420 +4.5, 0.9999999998033840 +5, 0.9999999999984630 +5.5, 0.9999999999999930 +6, 1.0 +32, 1.0 +-0.1, -0.1124629160182850 +-1, -0.8427007929497150 +TRUE, "#VALUE!" +FALSE, "#VALUE!" +"2", 0.9953222650189530 +"TWO", "#VALUE!" +-1.5, -1.5, 0.0 +-0.75, -1.5, -0.2549495128217960 +0, -1.5, -0.9661051464753110 +0.75, -1.5, -1.6772607801288300 +1.5, -1.5, -1.9322102929506200 +2.25, -1.5, -1.9646424298886300 +3, -1.5, -1.9660830559783100 +3.75, -1.5, -1.9661050327480500 +4.5, -1.5, -1.9661051462786900 +-1.5, -0.75, 0.2549495128217960 +-0.75, -0.75, 0.0 +0, -0.75, -0.7111556336535150 +0.75, -0.75, -1.4223112673070300 +1.5, -0.75, -1.6772607801288300 +2.25, -0.75, -1.7096929170668300 +3, -0.75, -1.7111335431565200 +3.75, -0.75, -1.7111555199262600 +4.5, -0.75, -1.7111556334569000 +-1.5, 0, 0.9661051464753110 +-0.75, 0, 0.7111556336535150 +0, 0, 0.0 +0.75, 0, -0.7111556336535150 +1.5, 0, -0.9661051464753110 +2.25, 0, -0.9985372834133190 +3, 0, -0.9999779095030010 +3.75, 0, -0.9999998862727430 +4.5, 0, -0.9999999998033840 +-1.5, 0.75, 1.6772607801288300 +-0.75, 0.75, 1.4223112673070300 +0, 0.75, 0.7111556336535150 +0.75, 0.75, 0.0 +1.5, 0.75, -0.2549495128217960 +2.25, 0.75, -0.2873816497598040 +3, 0.75, -0.2888222758494860 +3.75, 0.75, -0.2888442526192280 +4.5, 0.75, -0.2888443661498690 +-1.5, 1.5, 1.9322102929506200 +-0.75, 1.5, 1.6772607801288300 +0, 1.5, 0.9661051464753110 +0.75, 1.5, 0.2549495128217960 +1.5, 1.5, 0.0 +2.25, 1.5, -0.0324321369380081 +3, 1.5, -0.0338727630276906 +3.75, 1.5, -0.0338947397974326 +4.5, 1.5, -0.0338948533280732 +-1.5, 2.25, 1.9646424298886300 +-0.75, 2.25, 1.7096929170668300 +0, 2.25, 0.9985372834133190 +0.75, 2.25, 0.2873816497598040 +1.5, 2.25, 0.0324321369380081 +2.25, 2.25, 0.0 +3, 2.25, -0.0014406260896825 +3.75, 2.25, -0.0014626028594246 +4.5, 2.25, -0.0014627163900651 +-1.5, 3, 1.9660830559783100 +-0.75, 3, 1.7111335431565200 +0, 3, 0.9999779095030010 +0.75, 3, 0.2888222758494860 +1.5, 3, 0.0338727630276906 +2.25, 3, 0.0014406260896825 +3, 3, 0.0 +3.75, 3, -0.0000219767697420 +4.5, 3, -0.0000220903003826 +-1.5, 3.75, 1.9661050327480500 +-0.75, 3.75, 1.7111555199262600 +0, 3.75, 0.9999998862727430 +0.75, 3.75, 0.2888442526192280 +1.5, 3.75, 0.0338947397974326 +2.25, 3.75, 0.0014626028594246 +3, 3.75, 0.0000219767697420 +3.75, 3.75, 0.0 +4.5, 3.75, -0.0000001135306406 +-1.5, 4.5, 1.9661051462786900 +-0.75, 4.5, 1.7111556334569000 +0, 4.5, 0.9999999998033840 +0.75, 4.5, 0.2888443661498690 +1.5, 4.5, 0.0338948533280732 +2.25, 4.5, 0.0014627163900651 +3, 4.5, 0.0000220903003826 +3.75, 4.5, 0.0000001135306406 +4.5, 4.5, 0.0 +5, -1, -1.8427007929481800 +-5, 1, 1.8427007929481800 diff --git a/unitTests/rawTestData/Calculation/Engineering/ERFC.data b/unitTests/rawTestData/Calculation/Engineering/ERFC.data index d3c2fc57..3cdc3d5b 100644 --- a/unitTests/rawTestData/Calculation/Engineering/ERFC.data +++ b/unitTests/rawTestData/Calculation/Engineering/ERFC.data @@ -1,82 +1,41 @@ --2.5, 5, 0 --1.5, -1.5, 0 --0.75, -1.5, 0 -0, -1.5, 0 -0.75, -1.5, 0.288844366 -1.5, -1.5, 0.033894854 -2.25, -1.5, 0.001462717 -3, -1.5, 2.20905E-05 -3.75, -1.5, 1.13727E-07 -4.5, -1.5, 1.96616E-10 --1.5, -0.75, 0 --0.75, -0.75, 0 -0, -0.75, 0 -0.75, -0.75, 0.288844366 -1.5, -0.75, 0.033894854 -2.25, -0.75, 0.001462717 -3, -0.75, 2.20905E-05 -3.75, -0.75, 1.13727E-07 -4.5, -0.75, 1.96616E-10 --1.5, 0, 0 --0.75, 0, 0 -0, 0, 0 -0.75, 0, 0.288844366 -1.5, 0, 0.033894854 -2.25, 0, 0.001462717 -3, 0, 2.20905E-05 -3.75, 0, 1.13727E-07 -4.5, 0, 1.96616E-10 --1.5, 0.75, 0 --0.75, 0.75, 0 -0, 0.75, 0 -0.75, 0.75, 0.288844366 -1.5, 0.75, 0.033894854 -2.25, 0.75, 0.001462717 -3, 0.75, 2.20905E-05 -3.75, 0.75, 1.13727E-07 -4.5, 0.75, 1.96616E-10 --1.5, 1.5, 0 --0.75, 1.5, 0 -0, 1.5, 0 -0.75, 1.5, 0.288844366 -1.5, 1.5, 0.033894854 -2.25, 1.5, 0.001462717 -3, 1.5, 2.20905E-05 -3.75, 1.5, 1.13727E-07 -4.5, 1.5, 1.96616E-10 --1.5, 2.25, 0 --0.75, 2.25, 0 -0, 2.25, 0 -0.75, 2.25, 0.288844366 -1.5, 2.25, 0.033894854 -2.25, 2.25, 0.001462717 -3, 2.25, 2.20905E-05 -3.75, 2.25, 1.13727E-07 -4.5, 2.25, 1.96616E-10 --1.5, 3, 0 --0.75, 3, 0 -0, 3, 0 -0.75, 3, 0.288844366 -1.5, 3, 0.033894854 -2.25, 3, 0.001462717 -3, 3, 2.20905E-05 -3.75, 3, 1.13727E-07 -4.5, 3, 1.96616E-10 --1.5, 3.75, 0 --0.75, 3.75, 0 -0, 3.75, 0 -0.75, 3.75, 0.288844366 -1.5, 3.75, 0.033894854 -2.25, 3.75, 0.001462717 -3, 3.75, 2.20905E-05 -3.75, 3.75, 1.13727E-07 -4.5, 3.75, 1.96616E-10 --1.5, 4.5, 0 --0.75, 4.5, 0 -0, 4.5, 0 -0.75, 4.5, 0.288844366 -1.5, 4.5, 0.033894854 -2.25, 4.5, 0.001462717 -3, 4.5, 2.20905E-05 -3.75, 4.5, 1.13727E-07 -4.5, 4.5, 1.96616E-10 +# x value Result +0, 1.0 +0.01, 0.9887165844441500 +0.05, 0.9436280222029830 +0.1, 0.8875370839817150 +0.125, 0.8596837951986660 +0.15, 0.8320040285726360 +0.2, 0.7772974107895220 +0.25, 0.7236736098317630 +0.3, 0.6713732405408730 +0.35, 0.6206179464376900 +0.4, 0.5716076449533320 +0.45, 0.5245182802130760 +0.5, 0.4795001221869530 +0.6, 0.3961439091520740 +0.7, 0.3221988061625820 +0.8, 0.2578990352923390 +0.9, 0.2030917875771680 +1, 0.1572992070502850 +1.1, 0.1197949304259180 +1.2, 0.0896860217703646 +1.3, 0.0659920550593475 +1.4, 0.0477148802373512 +1.5, 0.0338948535246893 +1.75, 0.0133283287808176 +2, 0.0046777349810473 +2.5, 0.0004069520174450 +3, 0.0000220904969986 +3.5, 0.0000007430983723 +4, 0.0000000154172579 +4.5, 0.0000000001966160 +5, 0.0000000000015375 +5.5, 0.0000000000000074 +6, 0.0 +32, 0.0 +-0.1, 1.1124629160182900 +-1, 1.8427007929497100 +TRUE, "#VALUE!" +FALSE, "#VALUE!" +"2", 0.0046777349810473 +"TWO", "#VALUE!"