diff --git a/samples/bulkReadTest.php b/samples/bulkReadTest.php new file mode 100644 index 00000000..2f94d420 --- /dev/null +++ b/samples/bulkReadTest.php @@ -0,0 +1,38 @@ +disconnectWorksheets(); + $spreadsheet->garbageCollect(); + unset($spreadsheet); + echo 'Unset Spreadsheet', PHP_EOL; + gc_collect_cycles(); + echo 'Memory usage after unset: ' , (memory_get_usage(true) / 1024) , ' KB' , PHP_EOL; +} + +// Echo memory usage +echo ' Current memory usage: ' , (memory_get_usage(true) / 1024) , ' KB' , PHP_EOL; +echo ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024) , ' KB' , PHP_EOL; diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 36ce3c54..36381dbe 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -993,12 +993,12 @@ class Calculation ], 'FACT' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Fact::class, 'evaluate'], + 'functionCall' => [MathTrig\Factorial::class, 'fact'], 'argumentCount' => '1', ], 'FACTDOUBLE' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\FactDouble::class, 'evaluate'], + 'functionCall' => [MathTrig\Factorial::class, 'factDouble'], 'argumentCount' => '1', ], 'FALSE' => [ @@ -1729,12 +1729,12 @@ class Calculation ], 'MROUND' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Mround::class, 'evaluate'], + 'functionCall' => [MathTrig\Round::class, 'multiple'], 'argumentCount' => '2', ], 'MULTINOMIAL' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Multinomial::class, 'evaluate'], + 'functionCall' => [MathTrig\Factorial::class, 'multinomial'], 'argumentCount' => '1+', ], 'MUNIT' => [ @@ -2046,7 +2046,7 @@ class Calculation ], 'RAND' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Random::class, 'randNoArgs'], + 'functionCall' => [MathTrig\Random::class, 'rand'], 'argumentCount' => '0', ], 'RANDARRAY' => [ @@ -2116,17 +2116,17 @@ class Calculation ], 'ROUND' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Round::class, 'evaluate'], + 'functionCall' => [MathTrig\Round::class, 'round'], 'argumentCount' => '2', ], 'ROUNDDOWN' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\RoundDown::class, 'evaluate'], + 'functionCall' => [MathTrig\Round::class, 'down'], 'argumentCount' => '2', ], 'ROUNDUP' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\RoundUp::class, 'evaluate'], + 'functionCall' => [MathTrig\Round::class, 'up'], 'argumentCount' => '2', ], 'ROW' => [ diff --git a/src/PhpSpreadsheet/Calculation/MathTrig.php b/src/PhpSpreadsheet/Calculation/MathTrig.php index 903178cc..d7e1a66f 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig.php @@ -184,16 +184,16 @@ class MathTrig * * @Deprecated 1.18.0 * - * @see MathTrig\Fact::evaluate() - * Use the evaluate() method in the MathTrig\Fact class instead - * * @param float $factVal Factorial Value * * @return float|int|string Factorial, or a string containing an error + * + *@see MathTrig\Factorial::fact() + * Use the fact() method in the MathTrig\Factorial class instead */ public static function FACT($factVal) { - return MathTrig\Fact::evaluate($factVal); + return MathTrig\Factorial::fact($factVal); } /** @@ -206,16 +206,16 @@ class MathTrig * * @Deprecated 1.18.0 * - * @see MathTrig\FactDouble::evaluate() - * Use the evaluate() method in the MathTrig\FactDouble class instead - * * @param float $factVal Factorial Value * * @return float|int|string Double Factorial, or a string containing an error + * + *@see MathTrig\Factorial::factDouble() + * Use the factDouble() method in the MathTrig\Factorial class instead */ public static function FACTDOUBLE($factVal) { - return MathTrig\FactDouble::evaluate($factVal); + return MathTrig\Factorial::factDouble($factVal); } /** @@ -469,17 +469,17 @@ class MathTrig * * @Deprecated 1.17.0 * - * @see MathTrig\Mround::evaluate() - * Use the evaluate() method in the MathTrig\Mround class instead - * * @param float $number Number to round * @param int $multiple Multiple to which you want to round $number * * @return float|string Rounded Number, or a string containing an error + * + *@see MathTrig\Round::multiple() + * Use the multiple() method in the MathTrig\Mround class instead */ public static function MROUND($number, $multiple) { - return MathTrig\Mround::evaluate($number, $multiple); + return MathTrig\Round::multiple($number, $multiple); } /** @@ -489,8 +489,8 @@ class MathTrig * * @Deprecated 1.18.0 * - * @See MathTrig\Multinomial::evaluate() - * Use the evaluate method in the MathTrig\Multinomial class instead + * @See MathTrig\Factorial::multinomial() + * Use the multinomial method in the MathTrig\Factorial class instead * * @param mixed[] $args An array of mixed values for the Data Series * @@ -498,7 +498,7 @@ class MathTrig */ public static function MULTINOMIAL(...$args) { - return MathTrig\Multinomial::evaluate(...$args); + return MathTrig\Factorial::multinomial(...$args); } /** @@ -631,8 +631,8 @@ class MathTrig * * @Deprecated 1.17.0 * - * @See MathTrig\RoundUp::evaluate() - * Use the evaluate() method in the MathTrig\RoundUp class instead + * @See MathTrig\Round::up() + * Use the up() method in the MathTrig\Round class instead * * @param float $number Number to round * @param int $digits Number of digits to which you want to round $number @@ -641,7 +641,7 @@ class MathTrig */ public static function ROUNDUP($number, $digits) { - return MathTrig\RoundUp::evaluate($number, $digits); + return MathTrig\Round::up($number, $digits); } /** @@ -651,8 +651,8 @@ class MathTrig * * @Deprecated 1.17.0 * - * @See MathTrig\RoundDown::evaluate() - * Use the evaluate() method in the MathTrig\RoundDown class instead + * @See MathTrig\Round::down() + * Use the down() method in the MathTrig\Round class instead * * @param float $number Number to round * @param int $digits Number of digits to which you want to round $number @@ -661,7 +661,7 @@ class MathTrig */ public static function ROUNDDOWN($number, $digits) { - return MathTrig\RoundDown::evaluate($number, $digits); + return MathTrig\Round::down($number, $digits); } /** @@ -1124,8 +1124,8 @@ class MathTrig * * @Deprecated 1.17.0 * - * @See MathTrig\Round::evaluate() - * Use the evaluate() method in the MathTrig\Round class instead + * @See MathTrig\Round::round() + * Use the round() method in the MathTrig\Round class instead * * @param mixed $number Should be numeric * @param mixed $precision Should be int @@ -1134,7 +1134,7 @@ class MathTrig */ public static function builtinROUND($number, $precision) { - return MathTrig\Round::evaluate($number, $precision); + return MathTrig\Round::round($number, $precision); } /** diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php b/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php index 7e7b26ee..2a0cbdfd 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php @@ -31,7 +31,7 @@ class Combinations return $e->getMessage(); } - return round(Fact::evaluate($numObjs) / Fact::evaluate($numObjs - $numInSet)) / Fact::evaluate($numInSet); + return round(Factorial::fact($numObjs) / Factorial::fact($numObjs - $numInSet)) / Factorial::fact($numInSet); } /** @@ -69,6 +69,6 @@ class Combinations return $e->getMessage(); } - return round(Fact::evaluate($numObjs + $numInSet - 1) / Fact::evaluate($numObjs - 1)) / Fact::evaluate($numInSet); + return round(Factorial::fact($numObjs + $numInSet - 1) / Factorial::fact($numObjs - 1)) / Factorial::fact($numInSet); } } diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Fact.php b/src/PhpSpreadsheet/Calculation/MathTrig/Fact.php deleted file mode 100644 index 2aa3d349..00000000 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Fact.php +++ /dev/null @@ -1,47 +0,0 @@ -getMessage(); - } - - $factLoop = floor($factVal); - if ($factVal > $factLoop) { - if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) { - return Statistical\Distributions\Gamma::gammaValue($factVal + 1); - } - } - - $factorial = 1; - while ($factLoop > 1) { - $factorial *= $factLoop--; - } - - return $factorial; - } -} diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/FactDouble.php b/src/PhpSpreadsheet/Calculation/MathTrig/FactDouble.php deleted file mode 100644 index 4b760144..00000000 --- a/src/PhpSpreadsheet/Calculation/MathTrig/FactDouble.php +++ /dev/null @@ -1,39 +0,0 @@ -getMessage(); - } - - $factLoop = floor($factVal); - $factorial = 1; - while ($factLoop > 1) { - $factorial *= $factLoop; - $factLoop -= 2; - } - - return $factorial; - } -} diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php b/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php new file mode 100644 index 00000000..f443f8e5 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Factorial.php @@ -0,0 +1,110 @@ +getMessage(); + } + + $factLoop = floor($factVal); + if ($factVal > $factLoop) { + if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) { + return Statistical\Distributions\Gamma::gammaValue($factVal + 1); + } + } + + $factorial = 1; + while ($factLoop > 1) { + $factorial *= $factLoop--; + } + + return $factorial; + } + + /** + * FACTDOUBLE. + * + * Returns the double factorial of a number. + * + * Excel Function: + * FACTDOUBLE(factVal) + * + * @param float $factVal Factorial Value + * + * @return float|int|string Double Factorial, or a string containing an error + */ + public static function factDouble($factVal) + { + try { + $factVal = Helpers::validateNumericNullSubstitution($factVal, 0); + Helpers::validateNotNegative($factVal); + } catch (Exception $e) { + return $e->getMessage(); + } + + $factLoop = floor($factVal); + $factorial = 1; + while ($factLoop > 1) { + $factorial *= $factLoop; + $factLoop -= 2; + } + + return $factorial; + } + + /** + * MULTINOMIAL. + * + * Returns the ratio of the factorial of a sum of values to the product of factorials. + * + * @param mixed[] $args An array of mixed values for the Data Series + * + * @return float|string The result, or a string containing an error + */ + public static function multinomial(...$args) + { + $summer = 0; + $divisor = 1; + + try { + // Loop through arguments + foreach (Functions::flattenArray($args) as $argx) { + $arg = Helpers::validateNumericNullSubstitution($argx, null); + Helpers::validateNotNegative($arg); + $arg = (int) $arg; + $summer += $arg; + $divisor *= self::fact($arg); + } + } catch (Exception $e) { + return $e->getMessage(); + } + + $summer = self::fact($summer); + + return $summer / $divisor; + } +} diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Mround.php b/src/PhpSpreadsheet/Calculation/MathTrig/Mround.php deleted file mode 100644 index 5f3c4c05..00000000 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Mround.php +++ /dev/null @@ -1,40 +0,0 @@ -getMessage(); - } - - if ($number == 0 || $multiple == 0) { - return 0; - } - if ((Helpers::returnSign($number)) == (Helpers::returnSign($multiple))) { - $multiplier = 1 / $multiple; - - return round($number * $multiplier) / $multiplier; - } - - return Functions::NAN(); - } -} diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Multinomial.php b/src/PhpSpreadsheet/Calculation/MathTrig/Multinomial.php deleted file mode 100644 index 98b7d522..00000000 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Multinomial.php +++ /dev/null @@ -1,41 +0,0 @@ -getMessage(); - } - - $summer = Fact::evaluate($summer); - - return $summer / $divisor; - } -} diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Random.php b/src/PhpSpreadsheet/Calculation/MathTrig/Random.php index 1a384fe9..0c7acf91 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Random.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Random.php @@ -11,7 +11,7 @@ class Random * * @return float Random number */ - public static function randNoArgs() + public static function rand() { return (mt_rand(0, 10000000)) / 10000000; } diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Round.php b/src/PhpSpreadsheet/Calculation/MathTrig/Round.php index a6552321..b5a2c305 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Round.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Round.php @@ -2,7 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; -use Exception; +use PhpOffice\PhpSpreadsheet\Calculation\Exception; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Round { @@ -16,7 +17,7 @@ class Round * * @return float|string Rounded number */ - public static function evaluate($number, $precision) + public static function round($number, $precision) { try { $number = Helpers::validateNumericNullBool($number); @@ -27,4 +28,95 @@ class Round return round($number, (int) $precision); } + + /** + * ROUNDUP. + * + * Rounds a number up to a specified number of decimal places + * + * @param float $number Number to round + * @param int $digits Number of digits to which you want to round $number + * + * @return float|string Rounded Number, or a string containing an error + */ + public static function up($number, $digits) + { + try { + $number = Helpers::validateNumericNullBool($number); + $digits = (int) Helpers::validateNumericNullSubstitution($digits, null); + } catch (Exception $e) { + return $e->getMessage(); + } + + if ($number == 0.0) { + return 0.0; + } + + if ($number < 0.0) { + return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN); + } + + return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN); + } + + /** + * ROUNDDOWN. + * + * Rounds a number down to a specified number of decimal places + * + * @param float $number Number to round + * @param int $digits Number of digits to which you want to round $number + * + * @return float|string Rounded Number, or a string containing an error + */ + public static function down($number, $digits) + { + try { + $number = Helpers::validateNumericNullBool($number); + $digits = (int) Helpers::validateNumericNullSubstitution($digits, null); + } catch (Exception $e) { + return $e->getMessage(); + } + + if ($number == 0.0) { + return 0.0; + } + + if ($number < 0.0) { + return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP); + } + + return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP); + } + + /** + * MROUND. + * + * Rounds a number to the nearest multiple of a specified value + * + * @param mixed $number Expect float. Number to round. + * @param mixed $multiple Expect int. Multiple to which you want to round. + * + * @return float|string Rounded Number, or a string containing an error + */ + public static function multiple($number, $multiple) + { + try { + $number = Helpers::validateNumericNullSubstitution($number, 0); + $multiple = Helpers::validateNumericNullSubstitution($multiple, null); + } catch (Exception $e) { + return $e->getMessage(); + } + + if ($number == 0 || $multiple == 0) { + return 0; + } + if ((Helpers::returnSign($number)) == (Helpers::returnSign($multiple))) { + $multiplier = 1 / $multiple; + + return round($number * $multiplier) / $multiplier; + } + + return Functions::NAN(); + } } diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/RoundDown.php b/src/PhpSpreadsheet/Calculation/MathTrig/RoundDown.php deleted file mode 100644 index 0054a227..00000000 --- a/src/PhpSpreadsheet/Calculation/MathTrig/RoundDown.php +++ /dev/null @@ -1,38 +0,0 @@ -getMessage(); - } - - if ($number == 0.0) { - return 0.0; - } - - if ($number < 0.0) { - return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP); - } - - return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP); - } -} diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/RoundUp.php b/src/PhpSpreadsheet/Calculation/MathTrig/RoundUp.php deleted file mode 100644 index 6b2e6d1a..00000000 --- a/src/PhpSpreadsheet/Calculation/MathTrig/RoundUp.php +++ /dev/null @@ -1,38 +0,0 @@ -getMessage(); - } - - if ($number == 0.0) { - return 0.0; - } - - if ($number < 0.0) { - return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN); - } - - return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN); - } -} diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php index 3456efcc..e7252e02 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php @@ -42,12 +42,12 @@ class Poisson $summer = 0; $floor = floor($value); for ($i = 0; $i <= $floor; ++$i) { - $summer += $mean ** $i / MathTrig\Fact::evaluate($i); + $summer += $mean ** $i / MathTrig\Factorial::fact($i); } return exp(0 - $mean) * $summer; } - return (exp(0 - $mean) * $mean ** $value) / MathTrig\Fact::evaluate($value); + return (exp(0 - $mean) * $mean ** $value) / MathTrig\Factorial::fact($value); } } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php b/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php index ab2e14dd..0bad2a88 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php @@ -38,7 +38,7 @@ class Permutations return Functions::NAN(); } - return (int) round(MathTrig\Fact::evaluate($numObjs) / MathTrig\Fact::evaluate($numObjs - $numInSet)); + return (int) round(MathTrig\Factorial::fact($numObjs) / MathTrig\Factorial::fact($numObjs - $numInSet)); } /** diff --git a/src/PhpSpreadsheet/Calculation/TextData/Format.php b/src/PhpSpreadsheet/Calculation/TextData/Format.php index b360a0f6..d352c917 100644 --- a/src/PhpSpreadsheet/Calculation/TextData/Format.php +++ b/src/PhpSpreadsheet/Calculation/TextData/Format.php @@ -42,7 +42,7 @@ class Format if ($value < 0) { $round = 0 - $round; } - $value = MathTrig\Mround::evaluate($value, $round); + $value = MathTrig\Round::multiple($value, $round); } $mask = "$mask;($mask)";