Merge pull request #2583 from PHPOffice/Issue-2551_Enable-Array-Readiness-for-Functions-Maths
Issue 2551 - Enable array-readiness for more Math/Trig functions
This commit is contained in:
commit
866dd38611
|
|
@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Improved support for passing of array arguments to Excel function implementations to return array results (where appropriate). [PR #2562](https://github.com/PHPOffice/PhpSpreadsheet/pull/2562)
|
- Improved support for passing of array arguments to Excel function implementations to return array results (where appropriate). [Issue #2551](https://github.com/PHPOffice/PhpSpreadsheet/issues/2551)
|
||||||
|
|
||||||
This is the first stage in an ongoing process of adding array support to all appropriate function implementations,
|
This is the first stage in an ongoing process of adding array support to all appropriate function implementations,
|
||||||
- Support for the Excel365 Math/Trig SEQUENCE() function [PR #2536](https://github.com/PHPOffice/PhpSpreadsheet/pull/2536)
|
- Support for the Excel365 Math/Trig SEQUENCE() function [PR #2536](https://github.com/PHPOffice/PhpSpreadsheet/pull/2536)
|
||||||
|
|
|
||||||
|
|
@ -455,7 +455,7 @@ class MathTrig
|
||||||
* @param int $a Dividend
|
* @param int $a Dividend
|
||||||
* @param int $b Divisor
|
* @param int $b Divisor
|
||||||
*
|
*
|
||||||
* @return float|int|string Remainder, or a string containing an error
|
* @return array|float|int|string Remainder, or a string containing an error
|
||||||
*/
|
*/
|
||||||
public static function MOD($a = 1, $b = 1)
|
public static function MOD($a = 1, $b = 1)
|
||||||
{
|
{
|
||||||
|
|
@ -533,7 +533,7 @@ class MathTrig
|
||||||
* @param float $x
|
* @param float $x
|
||||||
* @param float $y
|
* @param float $y
|
||||||
*
|
*
|
||||||
* @return float|int|string The result, or a string containing an error
|
* @return array|float|int|string The result, or a string containing an error
|
||||||
*/
|
*/
|
||||||
public static function POWER($x = 0, $y = 2)
|
public static function POWER($x = 0, $y = 2)
|
||||||
{
|
{
|
||||||
|
|
@ -579,7 +579,7 @@ class MathTrig
|
||||||
* @param mixed $numerator
|
* @param mixed $numerator
|
||||||
* @param mixed $denominator
|
* @param mixed $denominator
|
||||||
*
|
*
|
||||||
* @return int|string
|
* @return array|int|string
|
||||||
*/
|
*/
|
||||||
public static function QUOTIENT($numerator, $denominator)
|
public static function QUOTIENT($numerator, $denominator)
|
||||||
{
|
{
|
||||||
|
|
@ -617,7 +617,7 @@ class MathTrig
|
||||||
* @param mixed $aValue Number to convert
|
* @param mixed $aValue Number to convert
|
||||||
* @param mixed $style Number indicating one of five possible forms
|
* @param mixed $style Number indicating one of five possible forms
|
||||||
*
|
*
|
||||||
* @return string Roman numeral, or a string containing an error
|
* @return array|string Roman numeral, or a string containing an error
|
||||||
*/
|
*/
|
||||||
public static function ROMAN($aValue, $style = 0)
|
public static function ROMAN($aValue, $style = 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,32 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
class Operations
|
class Operations
|
||||||
{
|
{
|
||||||
|
use ArrayEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MOD.
|
* MOD.
|
||||||
*
|
*
|
||||||
* @param mixed $dividend Dividend
|
* @param mixed $dividend Dividend
|
||||||
|
* Or can be an array of values
|
||||||
* @param mixed $divisor Divisor
|
* @param mixed $divisor Divisor
|
||||||
|
* Or can be an array of values
|
||||||
*
|
*
|
||||||
* @return float|int|string Remainder, or a string containing an error
|
* @return array|float|int|string Remainder, or a string containing an error
|
||||||
|
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||||
|
* with the same dimensions
|
||||||
*/
|
*/
|
||||||
public static function mod($dividend, $divisor)
|
public static function mod($dividend, $divisor)
|
||||||
{
|
{
|
||||||
|
if (is_array($dividend) || is_array($divisor)) {
|
||||||
|
return self::evaluateArrayArguments([self::class, __FUNCTION__], $dividend, $divisor);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$dividend = Helpers::validateNumericNullBool($dividend);
|
$dividend = Helpers::validateNumericNullBool($dividend);
|
||||||
$divisor = Helpers::validateNumericNullBool($divisor);
|
$divisor = Helpers::validateNumericNullBool($divisor);
|
||||||
|
|
@ -40,13 +51,21 @@ class Operations
|
||||||
*
|
*
|
||||||
* Computes x raised to the power y.
|
* Computes x raised to the power y.
|
||||||
*
|
*
|
||||||
* @param float|int $x
|
* @param array|float|int $x
|
||||||
* @param float|int $y
|
* Or can be an array of values
|
||||||
|
* @param array|float|int $y
|
||||||
|
* Or can be an array of values
|
||||||
*
|
*
|
||||||
* @return float|int|string The result, or a string containing an error
|
* @return array|float|int|string The result, or a string containing an error
|
||||||
|
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||||
|
* with the same dimensions
|
||||||
*/
|
*/
|
||||||
public static function power($x, $y)
|
public static function power($x, $y)
|
||||||
{
|
{
|
||||||
|
if (is_array($x) || is_array($y)) {
|
||||||
|
return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $y);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$x = Helpers::validateNumericNullBool($x);
|
$x = Helpers::validateNumericNullBool($x);
|
||||||
$y = Helpers::validateNumericNullBool($y);
|
$y = Helpers::validateNumericNullBool($y);
|
||||||
|
|
@ -117,12 +136,20 @@ class Operations
|
||||||
* QUOTIENT(value1,value2)
|
* QUOTIENT(value1,value2)
|
||||||
*
|
*
|
||||||
* @param mixed $numerator Expect float|int
|
* @param mixed $numerator Expect float|int
|
||||||
|
* Or can be an array of values
|
||||||
* @param mixed $denominator Expect float|int
|
* @param mixed $denominator Expect float|int
|
||||||
|
* Or can be an array of values
|
||||||
*
|
*
|
||||||
* @return int|string
|
* @return array|int|string
|
||||||
|
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||||
|
* with the same dimensions
|
||||||
*/
|
*/
|
||||||
public static function quotient($numerator, $denominator)
|
public static function quotient($numerator, $denominator)
|
||||||
{
|
{
|
||||||
|
if (is_array($numerator) || is_array($denominator)) {
|
||||||
|
return self::evaluateArrayArguments([self::class, __FUNCTION__], $numerator, $denominator);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$numerator = Helpers::validateNumericNullSubstitution($numerator, 0);
|
$numerator = Helpers::validateNumericNullSubstitution($numerator, 0);
|
||||||
$denominator = Helpers::validateNumericNullSubstitution($denominator, 0);
|
$denominator = Helpers::validateNumericNullSubstitution($denominator, 0);
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,14 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
class Roman
|
class Roman
|
||||||
{
|
{
|
||||||
|
use ArrayEnabled;
|
||||||
|
|
||||||
private const VALUES = [
|
private const VALUES = [
|
||||||
45 => ['VL'],
|
45 => ['VL'],
|
||||||
46 => ['VLI'],
|
46 => ['VLI'],
|
||||||
|
|
@ -814,12 +817,20 @@ class Roman
|
||||||
* Converts a number to Roman numeral
|
* Converts a number to Roman numeral
|
||||||
*
|
*
|
||||||
* @param mixed $aValue Number to convert
|
* @param mixed $aValue Number to convert
|
||||||
|
* Or can be an array of numbers
|
||||||
* @param mixed $style Number indicating one of five possible forms
|
* @param mixed $style Number indicating one of five possible forms
|
||||||
|
* Or can be an array of styles
|
||||||
*
|
*
|
||||||
* @return string Roman numeral, or a string containing an error
|
* @return array|string Roman numeral, or a string containing an error
|
||||||
|
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||||
|
* with the same dimensions
|
||||||
*/
|
*/
|
||||||
public static function evaluate($aValue, $style = 0)
|
public static function evaluate($aValue, $style = 0)
|
||||||
{
|
{
|
||||||
|
if (is_array($aValue) || is_array($style)) {
|
||||||
|
return self::evaluateArrayArguments([self::class, __FUNCTION__], $aValue, $style);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$aValue = Helpers::validateNumericNullBool($aValue);
|
$aValue = Helpers::validateNumericNullBool($aValue);
|
||||||
if (is_bool($style)) {
|
if (is_bool($style)) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||||
|
|
||||||
class ModTest extends AllSetupTeardown
|
class ModTest extends AllSetupTeardown
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,4 +38,23 @@ class ModTest extends AllSetupTeardown
|
||||||
{
|
{
|
||||||
return require 'tests/data/Calculation/MathTrig/MOD.php';
|
return require 'tests/data/Calculation/MathTrig/MOD.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerModArray
|
||||||
|
*/
|
||||||
|
public function testModArray(array $expectedResult, string $argument1, string $argument2): void
|
||||||
|
{
|
||||||
|
$calculation = Calculation::getInstance();
|
||||||
|
|
||||||
|
$formula = "=MOD({$argument1}, {$argument2})";
|
||||||
|
$result = $calculation->_calculateFormulaValue($formula);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerModArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'matrix' => [[[4, 3, 2], [1, 0, 4], [3, 2, 1]], '{9, 8, 7; 6, 5, 4; 3, 2, 1}', '5'],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||||
|
|
||||||
class PowerTest extends AllSetupTeardown
|
class PowerTest extends AllSetupTeardown
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,4 +38,23 @@ class PowerTest extends AllSetupTeardown
|
||||||
{
|
{
|
||||||
return require 'tests/data/Calculation/MathTrig/POWER.php';
|
return require 'tests/data/Calculation/MathTrig/POWER.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerPowerArray
|
||||||
|
*/
|
||||||
|
public function testPowerArray(array $expectedResult, string $argument1, string $argument2): void
|
||||||
|
{
|
||||||
|
$calculation = Calculation::getInstance();
|
||||||
|
|
||||||
|
$formula = "=POWER({$argument1}, {$argument2})";
|
||||||
|
$result = $calculation->_calculateFormulaValue($formula);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerPowerArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'matrix' => [[[729, 512, 343], [216, 125, 64], [27, 8, 1]], '{9, 8, 7; 6, 5, 4; 3, 2, 1}', '3'],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||||
|
|
||||||
class QuotientTest extends AllSetupTeardown
|
class QuotientTest extends AllSetupTeardown
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,4 +38,23 @@ class QuotientTest extends AllSetupTeardown
|
||||||
{
|
{
|
||||||
return require 'tests/data/Calculation/MathTrig/QUOTIENT.php';
|
return require 'tests/data/Calculation/MathTrig/QUOTIENT.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerQuotientArray
|
||||||
|
*/
|
||||||
|
public function testQuotientArray(array $expectedResult, string $argument1, string $argument2): void
|
||||||
|
{
|
||||||
|
$calculation = Calculation::getInstance();
|
||||||
|
|
||||||
|
$formula = "=QUOTIENT({$argument1}, {$argument2})";
|
||||||
|
$result = $calculation->_calculateFormulaValue($formula);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerQuotientArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'matrix' => [[[3, 3, 2], [2, 2, 1], [1, 0, 0]], '{9, 8, 7; 6, 5, 4; 3, 2, 1}', '2.5'],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||||
|
|
||||||
class RomanTest extends AllSetupTeardown
|
class RomanTest extends AllSetupTeardown
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -24,4 +26,25 @@ class RomanTest extends AllSetupTeardown
|
||||||
{
|
{
|
||||||
return require 'tests/data/Calculation/MathTrig/ROMAN.php';
|
return require 'tests/data/Calculation/MathTrig/ROMAN.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerRomanArray
|
||||||
|
*/
|
||||||
|
public function testRomanArray(array $expectedResult, string $values, string $styles): void
|
||||||
|
{
|
||||||
|
$calculation = Calculation::getInstance();
|
||||||
|
|
||||||
|
$formula = "=ROMAN({$values}, {$styles})";
|
||||||
|
$result = $calculation->_calculateFormulaValue($formula);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerRomanArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'row vector' => [[['XLIX', 'MMXXII', 'CDXCIX']], '{49, 2022, 499}', '0'],
|
||||||
|
'column vector' => [[['XLIX'], ['MMXXII'], ['CDXCIX']], '{49; 2022; 499}', '0'],
|
||||||
|
'matrix' => [[['XLIX', 'MMXXII'], ['LXIV', 'CDXCIX']], '{49, 2022; 64, 499}', '0'],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue