Added support for the FLOOR.MATH and FLOOR.PRECISE functions
This commit is contained in:
parent
c4895b9468
commit
a6c56d0f81
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Improved the ARABIC function to also hande short-hand roman numerals
|
- Improved the ARABIC function to also hande short-hand roman numerals
|
||||||
|
- Added support for the FLOOR.MATH and FLOOR.PRECISE functions [#1351](https://github.com/PHPOffice/PhpSpreadsheet/pull/1351)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -914,6 +914,16 @@ class Calculation
|
||||||
'functionCall' => [MathTrig::class, 'FLOOR'],
|
'functionCall' => [MathTrig::class, 'FLOOR'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '2',
|
||||||
],
|
],
|
||||||
|
'FLOOR.MATH' => [
|
||||||
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
|
'functionCall' => [MathTrig::class, 'FLOORMATH'],
|
||||||
|
'argumentCount' => '3',
|
||||||
|
],
|
||||||
|
'FLOOR.PRECISE' => [
|
||||||
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
|
'functionCall' => [MathTrig::class, 'FLOORPRECISE'],
|
||||||
|
'argumentCount' => '2',
|
||||||
|
],
|
||||||
'FORECAST' => [
|
'FORECAST' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'FORECAST'],
|
'functionCall' => [Statistical::class, 'FORECAST'],
|
||||||
|
|
|
@ -438,6 +438,80 @@ class MathTrig
|
||||||
return Functions::VALUE();
|
return Functions::VALUE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FLOOR.MATH.
|
||||||
|
*
|
||||||
|
* Round a number down to the nearest integer or to the nearest multiple of significance.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* FLOOR.MATH(number[,significance[,mode]])
|
||||||
|
*
|
||||||
|
* @category Mathematical and Trigonometric Functions
|
||||||
|
*
|
||||||
|
* @param float $number Number to round
|
||||||
|
* @param float $significance Significance
|
||||||
|
* @param int $mode direction to round negative numbers
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function FLOORMATH($number, $significance = null, $mode = 0)
|
||||||
|
{
|
||||||
|
$number = Functions::flattenSingleValue($number);
|
||||||
|
$significance = Functions::flattenSingleValue($significance);
|
||||||
|
$mode = Functions::flattenSingleValue($mode);
|
||||||
|
|
||||||
|
if (is_numeric($number) && $significance === null) {
|
||||||
|
$significance = $number / abs($number);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_numeric($number) && is_numeric($significance) && is_numeric($mode)) {
|
||||||
|
if ($significance == 0.0) {
|
||||||
|
return Functions::DIV0();
|
||||||
|
} elseif ($number == 0.0) {
|
||||||
|
return 0.0;
|
||||||
|
} elseif (self::SIGN($significance) == -1 || (self::SIGN($number) == -1 && !empty($mode))) {
|
||||||
|
return ceil($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return floor($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FLOOR.PRECISE.
|
||||||
|
*
|
||||||
|
* Rounds number down, toward zero, to the nearest multiple of significance.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* FLOOR.PRECISE(number[,significance])
|
||||||
|
*
|
||||||
|
* @category Mathematical and Trigonometric Functions
|
||||||
|
*
|
||||||
|
* @param float $number Number to round
|
||||||
|
* @param float $significance Significance
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function FLOORPRECISE($number, $significance = 1)
|
||||||
|
{
|
||||||
|
$number = Functions::flattenSingleValue($number);
|
||||||
|
$significance = Functions::flattenSingleValue($significance);
|
||||||
|
|
||||||
|
if ((is_numeric($number)) && (is_numeric($significance))) {
|
||||||
|
if ($significance == 0.0) {
|
||||||
|
return Functions::DIV0();
|
||||||
|
} elseif ($number == 0.0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return floor($number / abs($significance)) * abs($significance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
private static function evaluateGCD($a, $b)
|
private static function evaluateGCD($a, $b)
|
||||||
{
|
{
|
||||||
return $b ? self::evaluateGCD($b, $a % $b) : $a;
|
return $b ? self::evaluateGCD($b, $a % $b) : $a;
|
||||||
|
|
|
@ -139,6 +139,8 @@ FISHER
|
||||||
FISHERINV
|
FISHERINV
|
||||||
FIXED
|
FIXED
|
||||||
FLOOR
|
FLOOR
|
||||||
|
FLOOR.MATH
|
||||||
|
FLOOR.PRECISE
|
||||||
FORECAST
|
FORECAST
|
||||||
FREQUENCY
|
FREQUENCY
|
||||||
FTEST
|
FTEST
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class FloorMathTest extends TestCase
|
||||||
|
{
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerFLOORMATH
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
*/
|
||||||
|
public function testFLOORMATH($expectedResult, ...$args)
|
||||||
|
{
|
||||||
|
$result = MathTrig::FLOORMATH(...$args);
|
||||||
|
$this->assertEquals($expectedResult, $result, '', 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerFLOORMATH()
|
||||||
|
{
|
||||||
|
return require 'data/Calculation/MathTrig/FLOORMATH.php';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class FloorPreciseTest extends TestCase
|
||||||
|
{
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerFLOORPRECISE
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
*/
|
||||||
|
public function testFLOOR($expectedResult, ...$args)
|
||||||
|
{
|
||||||
|
$result = MathTrig::FLOORPRECISE(...$args);
|
||||||
|
$this->assertEquals($expectedResult, $result, '', 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerFLOORPRECISE()
|
||||||
|
{
|
||||||
|
return require 'data/Calculation/MathTrig/FLOORPRECISE.php';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2.5,
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-4,
|
||||||
|
-2.5,
|
||||||
|
-2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-4,
|
||||||
|
-2.5,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2.5,
|
||||||
|
-2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#DIV/0!',
|
||||||
|
123.456,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1.5,
|
||||||
|
1.5,
|
||||||
|
0.10000000000000001,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.23000000000000001,
|
||||||
|
0.23400000000000001,
|
||||||
|
0.01,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
123,
|
||||||
|
123.456,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#VALUE!',
|
||||||
|
'ABC',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
15,
|
||||||
|
17,
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
16,
|
||||||
|
19,
|
||||||
|
4,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
20,
|
||||||
|
24.3,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
6,
|
||||||
|
6.7
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-10,
|
||||||
|
-8.1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-4,
|
||||||
|
-5.5,
|
||||||
|
2,
|
||||||
|
-1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-4,
|
||||||
|
-5.5,
|
||||||
|
2,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-6,
|
||||||
|
-5.5,
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
];
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2.5,
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-4,
|
||||||
|
-2.5,
|
||||||
|
-2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-4,
|
||||||
|
-2.5,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2.5,
|
||||||
|
-2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#DIV/0!',
|
||||||
|
123.456,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1.5,
|
||||||
|
1.5,
|
||||||
|
0.10000000000000001,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.23000000000000001,
|
||||||
|
0.23400000000000001,
|
||||||
|
0.01,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
123,
|
||||||
|
123.456,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#VALUE!',
|
||||||
|
'ABC',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
15,
|
||||||
|
17,
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
16,
|
||||||
|
19,
|
||||||
|
4,
|
||||||
|
],
|
||||||
|
];
|
Loading…
Reference in New Issue