diff --git a/CHANGELOG.md b/CHANGELOG.md index cbf1bdde..c2931dca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). ## [Unreleased] +- Added support for the BASE function - Added support for the ARABIC function - Conditionals - Extend Support for (NOT)CONTAINSBLANKS [#1278](https://github.com/PHPOffice/PhpSpreadsheet/pull/1278) - Handle Error in Formula Processing Better for Xls [#1267](https://github.com/PHPOffice/PhpSpreadsheet/pull/1267) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 1901e5d3..4ebce2ae 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -333,6 +333,11 @@ class Calculation 'functionCall' => [Functions::class, 'DUMMY'], 'argumentCount' => '1', ], + 'BASE' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'BASE'], + 'argumentCount' => '2,3', + ], 'BESSELI' => [ 'category' => Category::CATEGORY_ENGINEERING, 'functionCall' => [Engineering::class, 'BESSELI'], diff --git a/src/PhpSpreadsheet/Calculation/MathTrig.php b/src/PhpSpreadsheet/Calculation/MathTrig.php index 7ad78524..33bfee19 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig.php @@ -142,6 +142,49 @@ class MathTrig return Functions::VALUE(); } + /** + * BASE. + * + * Converts a number into a text representation with the given radix (base). + * + * Excel Function: + * BASE(Number, Radix [Min_length]) + * + * @category Mathematical and Trigonometric Functions + * + * @param float $number + * @param float $radix + * @param int $minLength + * + * @return string the text representation with the given radix (base) + */ + public static function BASE($number, $radix, $minLength = null) + { + $number = Functions::flattenSingleValue($number); + $radix = Functions::flattenSingleValue($radix); + $minLength = Functions::flattenSingleValue($minLength); + + if (is_numeric($number) && is_numeric($radix) && ($minLength === null || is_numeric($minLength))) { + // Truncate to an integer + $number = (int) $number; + $radix = (int) $radix; + $minLength = (int) $minLength; + + if ($number < 0 || $number >= 2 ** 53 || $radix < 2 || $radix > 36) { + return Functions::NAN(); // Numeric range constraints + } + + $outcome = strtoupper((string) base_convert($number, 10, $radix)); + if ($minLength !== null) { + $outcome = str_pad($outcome, $minLength, '0', STR_PAD_LEFT); // String padding + } + + return $outcome; + } + + return Functions::VALUE(); + } + /** * CEILING. * diff --git a/src/PhpSpreadsheet/Calculation/functionlist.txt b/src/PhpSpreadsheet/Calculation/functionlist.txt index 66523f4f..7776e6ea 100644 --- a/src/PhpSpreadsheet/Calculation/functionlist.txt +++ b/src/PhpSpreadsheet/Calculation/functionlist.txt @@ -23,6 +23,7 @@ AVERAGEA AVERAGEIF AVERAGEIFS BAHTTEXT +BASE BESSELI BESSELJ BESSELK diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php new file mode 100644 index 00000000..3aaf68b5 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerBASE() + { + return require 'data/Calculation/MathTrig/BASE.php'; + } +} diff --git a/tests/data/Calculation/MathTrig/BASE.php b/tests/data/Calculation/MathTrig/BASE.php new file mode 100644 index 00000000..c2802dd9 --- /dev/null +++ b/tests/data/Calculation/MathTrig/BASE.php @@ -0,0 +1,59 @@ +