Skip to content

Commit 866dd38

Browse files
author
Mark Baker
authored
Merge pull request #2583 from PHPOffice/Issue-2551_Enable-Array-Readiness-for-Functions-Maths
Issue 2551 - Enable array-readiness for more Math/Trig functions
2 parents 0eeba6d + 5d88c6b commit 866dd38

File tree

8 files changed

+135
-11
lines changed

8 files changed

+135
-11
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
1111

1212
### Added
1313

14-
- 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)
14+
- 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)
1515

1616
This is the first stage in an ongoing process of adding array support to all appropriate function implementations,
1717
- Support for the Excel365 Math/Trig SEQUENCE() function [PR #2536](https://github.com/PHPOffice/PhpSpreadsheet/pull/2536)

src/PhpSpreadsheet/Calculation/MathTrig.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ public static function MMULT($matrixData1, $matrixData2)
455455
* @param int $a Dividend
456456
* @param int $b Divisor
457457
*
458-
* @return float|int|string Remainder, or a string containing an error
458+
* @return array|float|int|string Remainder, or a string containing an error
459459
*/
460460
public static function MOD($a = 1, $b = 1)
461461
{
@@ -533,7 +533,7 @@ public static function ODD($number)
533533
* @param float $x
534534
* @param float $y
535535
*
536-
* @return float|int|string The result, or a string containing an error
536+
* @return array|float|int|string The result, or a string containing an error
537537
*/
538538
public static function POWER($x = 0, $y = 2)
539539
{
@@ -579,7 +579,7 @@ public static function PRODUCT(...$args)
579579
* @param mixed $numerator
580580
* @param mixed $denominator
581581
*
582-
* @return int|string
582+
* @return array|int|string
583583
*/
584584
public static function QUOTIENT($numerator, $denominator)
585585
{
@@ -617,7 +617,7 @@ public static function RAND($min = 0, $max = 0)
617617
* @param mixed $aValue Number to convert
618618
* @param mixed $style Number indicating one of five possible forms
619619
*
620-
* @return string Roman numeral, or a string containing an error
620+
* @return array|string Roman numeral, or a string containing an error
621621
*/
622622
public static function ROMAN($aValue, $style = 0)
623623
{

src/PhpSpreadsheet/Calculation/MathTrig/Operations.php

+32-5
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,32 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
56
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
67
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
78

89
class Operations
910
{
11+
use ArrayEnabled;
12+
1013
/**
1114
* MOD.
1215
*
1316
* @param mixed $dividend Dividend
17+
* Or can be an array of values
1418
* @param mixed $divisor Divisor
19+
* Or can be an array of values
1520
*
16-
* @return float|int|string Remainder, or a string containing an error
21+
* @return array|float|int|string Remainder, or a string containing an error
22+
* If an array of numbers is passed as an argument, then the returned result will also be an array
23+
* with the same dimensions
1724
*/
1825
public static function mod($dividend, $divisor)
1926
{
27+
if (is_array($dividend) || is_array($divisor)) {
28+
return self::evaluateArrayArguments([self::class, __FUNCTION__], $dividend, $divisor);
29+
}
30+
2031
try {
2132
$dividend = Helpers::validateNumericNullBool($dividend);
2233
$divisor = Helpers::validateNumericNullBool($divisor);
@@ -40,13 +51,21 @@ public static function mod($dividend, $divisor)
4051
*
4152
* Computes x raised to the power y.
4253
*
43-
* @param float|int $x
44-
* @param float|int $y
54+
* @param array|float|int $x
55+
* Or can be an array of values
56+
* @param array|float|int $y
57+
* Or can be an array of values
4558
*
46-
* @return float|int|string The result, or a string containing an error
59+
* @return array|float|int|string The result, or a string containing an error
60+
* If an array of numbers is passed as an argument, then the returned result will also be an array
61+
* with the same dimensions
4762
*/
4863
public static function power($x, $y)
4964
{
65+
if (is_array($x) || is_array($y)) {
66+
return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $y);
67+
}
68+
5069
try {
5170
$x = Helpers::validateNumericNullBool($x);
5271
$y = Helpers::validateNumericNullBool($y);
@@ -117,12 +136,20 @@ public static function product(...$args)
117136
* QUOTIENT(value1,value2)
118137
*
119138
* @param mixed $numerator Expect float|int
139+
* Or can be an array of values
120140
* @param mixed $denominator Expect float|int
141+
* Or can be an array of values
121142
*
122-
* @return int|string
143+
* @return array|int|string
144+
* If an array of numbers is passed as an argument, then the returned result will also be an array
145+
* with the same dimensions
123146
*/
124147
public static function quotient($numerator, $denominator)
125148
{
149+
if (is_array($numerator) || is_array($denominator)) {
150+
return self::evaluateArrayArguments([self::class, __FUNCTION__], $numerator, $denominator);
151+
}
152+
126153
try {
127154
$numerator = Helpers::validateNumericNullSubstitution($numerator, 0);
128155
$denominator = Helpers::validateNumericNullSubstitution($denominator, 0);

src/PhpSpreadsheet/Calculation/MathTrig/Roman.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
56
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
67
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
78

89
class Roman
910
{
11+
use ArrayEnabled;
12+
1013
private const VALUES = [
1114
45 => ['VL'],
1215
46 => ['VLI'],
@@ -814,12 +817,20 @@ public static function calculateRoman(int $aValue, int $style): string
814817
* Converts a number to Roman numeral
815818
*
816819
* @param mixed $aValue Number to convert
820+
* Or can be an array of numbers
817821
* @param mixed $style Number indicating one of five possible forms
822+
* Or can be an array of styles
818823
*
819-
* @return string Roman numeral, or a string containing an error
824+
* @return array|string Roman numeral, or a string containing an error
825+
* If an array of numbers is passed as an argument, then the returned result will also be an array
826+
* with the same dimensions
820827
*/
821828
public static function evaluate($aValue, $style = 0)
822829
{
830+
if (is_array($aValue) || is_array($style)) {
831+
return self::evaluateArrayArguments([self::class, __FUNCTION__], $aValue, $style);
832+
}
833+
823834
try {
824835
$aValue = Helpers::validateNumericNullBool($aValue);
825836
if (is_bool($style)) {

tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6+
57
class ModTest extends AllSetupTeardown
68
{
79
/**
@@ -36,4 +38,23 @@ public function providerMOD(): array
3638
{
3739
return require 'tests/data/Calculation/MathTrig/MOD.php';
3840
}
41+
42+
/**
43+
* @dataProvider providerModArray
44+
*/
45+
public function testModArray(array $expectedResult, string $argument1, string $argument2): void
46+
{
47+
$calculation = Calculation::getInstance();
48+
49+
$formula = "=MOD({$argument1}, {$argument2})";
50+
$result = $calculation->_calculateFormulaValue($formula);
51+
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
52+
}
53+
54+
public function providerModArray(): array
55+
{
56+
return [
57+
'matrix' => [[[4, 3, 2], [1, 0, 4], [3, 2, 1]], '{9, 8, 7; 6, 5, 4; 3, 2, 1}', '5'],
58+
];
59+
}
3960
}

tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6+
57
class PowerTest extends AllSetupTeardown
68
{
79
/**
@@ -36,4 +38,23 @@ public function providerPOWER(): array
3638
{
3739
return require 'tests/data/Calculation/MathTrig/POWER.php';
3840
}
41+
42+
/**
43+
* @dataProvider providerPowerArray
44+
*/
45+
public function testPowerArray(array $expectedResult, string $argument1, string $argument2): void
46+
{
47+
$calculation = Calculation::getInstance();
48+
49+
$formula = "=POWER({$argument1}, {$argument2})";
50+
$result = $calculation->_calculateFormulaValue($formula);
51+
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
52+
}
53+
54+
public function providerPowerArray(): array
55+
{
56+
return [
57+
'matrix' => [[[729, 512, 343], [216, 125, 64], [27, 8, 1]], '{9, 8, 7; 6, 5, 4; 3, 2, 1}', '3'],
58+
];
59+
}
3960
}

tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6+
57
class QuotientTest extends AllSetupTeardown
68
{
79
/**
@@ -36,4 +38,23 @@ public function providerQUOTIENT(): array
3638
{
3739
return require 'tests/data/Calculation/MathTrig/QUOTIENT.php';
3840
}
41+
42+
/**
43+
* @dataProvider providerQuotientArray
44+
*/
45+
public function testQuotientArray(array $expectedResult, string $argument1, string $argument2): void
46+
{
47+
$calculation = Calculation::getInstance();
48+
49+
$formula = "=QUOTIENT({$argument1}, {$argument2})";
50+
$result = $calculation->_calculateFormulaValue($formula);
51+
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
52+
}
53+
54+
public function providerQuotientArray(): array
55+
{
56+
return [
57+
'matrix' => [[[3, 3, 2], [2, 2, 1], [1, 0, 0]], '{9, 8, 7; 6, 5, 4; 3, 2, 1}', '2.5'],
58+
];
59+
}
3960
}

tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6+
57
class RomanTest extends AllSetupTeardown
68
{
79
/**
@@ -24,4 +26,25 @@ public function providerROMAN(): array
2426
{
2527
return require 'tests/data/Calculation/MathTrig/ROMAN.php';
2628
}
29+
30+
/**
31+
* @dataProvider providerRomanArray
32+
*/
33+
public function testRomanArray(array $expectedResult, string $values, string $styles): void
34+
{
35+
$calculation = Calculation::getInstance();
36+
37+
$formula = "=ROMAN({$values}, {$styles})";
38+
$result = $calculation->_calculateFormulaValue($formula);
39+
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
40+
}
41+
42+
public function providerRomanArray(): array
43+
{
44+
return [
45+
'row vector' => [[['XLIX', 'MMXXII', 'CDXCIX']], '{49, 2022, 499}', '0'],
46+
'column vector' => [[['XLIX'], ['MMXXII'], ['CDXCIX']], '{49; 2022; 499}', '0'],
47+
'matrix' => [[['XLIX', 'MMXXII'], ['LXIV', 'CDXCIX']], '{49, 2022; 64, 499}', '0'],
48+
];
49+
}
2750
}

0 commit comments

Comments
 (0)