ROUND Accepts null, false, and true as First Parameter (#1837)
* ROUND Accepts null, false, and true as First Parameter Issue #1789 was addressed by PR #1799. In a follow-up discussion, it came to light that ROUND was not handling the unexpected case where the first parameter is an empty cell in the same manner that Excel does. Subsequent investigation showed that a boolean first parameter is permitted. I broadened my investigation to include the following related functions. - ROUNDUP - ROUNDDOWN - MROUND - TRUNC - INT - FLOOR - FLOOR.MATH - FLOOR.PRECISE - CEILING - CEILING.MATH - CEILING.PRECISE All of these allow a NULL first parameter, and all except MROUND allow boolean. For completeness, I will note that all treat null string as invalid. I suspect there are other functions which permit similarly unexpected parameters, but I consider them out of scope for this PR. CEILING.MATH and CEILING.PRECISE were unimplemented, and are now supported as part of this PR. The tests for each of these functions have been re-coded, though all the original test data is still included in the test cases, plus several new cases for each. The new tests now take place as a user would invoke the functions, through a spreadsheet cell rather than a direct call to the appropriate function within Calculation/MathTrig. Aside from being more realistic, the new tests are also more complete. For example, FLOOR.MATH can take from 1-3 arguments, and the existing tests confirmed that the function in Calculation could handle a single argument. However, the function list in Calculation.php erroneously set the number of arguments for FLOOR.MATH to exactly 3, so, if a user tried to get the calculated result of a cell containing FLOOR.MATH(1.2), the result would be an Exception. Aside from the parameter support, there are a few minor code changes. Ods, as well as Gnumeric, allows the omission of the second parameter for FLOAT and CEILING; Excel does not. A potential divide-by-zero error is avoided in CEILING, FLOOR, and FLOORMATH. I will note that it would probably be beneficial in terms of maintainability to break MathTrig up into many individual modules. The same would hold for the other Calculation modules. I would be willing to look into this if you agree that it would be worthwhile.
This commit is contained in:
parent
c54e3e9979
commit
cabcfaa522
|
|
@ -463,18 +463,18 @@ class Calculation
|
||||||
],
|
],
|
||||||
'CEILING' => [
|
'CEILING' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'CEILING'],
|
'functionCall' => [MathTrig\Ceiling::class, 'funcCeiling'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '1-2', // 2 for Excel, 1-2 for Ods/Gnumeric
|
||||||
],
|
],
|
||||||
'CEILING.MATH' => [
|
'CEILING.MATH' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [Functions::class, 'DUMMY'],
|
'functionCall' => [MathTrig\CeilingMath::class, 'funcCeilingMath'],
|
||||||
'argumentCount' => '3',
|
'argumentCount' => '1-3',
|
||||||
],
|
],
|
||||||
'CEILING.PRECISE' => [
|
'CEILING.PRECISE' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [Functions::class, 'DUMMY'],
|
'functionCall' => [MathTrig\CeilingPrecise::class, 'funcCeilingPrecise'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '1,2',
|
||||||
],
|
],
|
||||||
'CELL' => [
|
'CELL' => [
|
||||||
'category' => Category::CATEGORY_INFORMATION,
|
'category' => Category::CATEGORY_INFORMATION,
|
||||||
|
|
@ -1069,18 +1069,18 @@ class Calculation
|
||||||
],
|
],
|
||||||
'FLOOR' => [
|
'FLOOR' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'FLOOR'],
|
'functionCall' => [MathTrig\Floor::class, 'funcFloor'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '1-2', // Excel requries 2, Ods/Gnumeric 1-2
|
||||||
],
|
],
|
||||||
'FLOOR.MATH' => [
|
'FLOOR.MATH' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'FLOORMATH'],
|
'functionCall' => [MathTrig\FloorMath::class, 'funcFloorMath'],
|
||||||
'argumentCount' => '3',
|
'argumentCount' => '1-3',
|
||||||
],
|
],
|
||||||
'FLOOR.PRECISE' => [
|
'FLOOR.PRECISE' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'FLOORPRECISE'],
|
'functionCall' => [MathTrig\FloorPrecise::class, 'funcFloorPrecise'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '1-2',
|
||||||
],
|
],
|
||||||
'FORECAST' => [
|
'FORECAST' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
|
|
@ -1418,7 +1418,7 @@ class Calculation
|
||||||
],
|
],
|
||||||
'INT' => [
|
'INT' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'INT'],
|
'functionCall' => [MathTrig\IntClass::class, 'funcInt'],
|
||||||
'argumentCount' => '1',
|
'argumentCount' => '1',
|
||||||
],
|
],
|
||||||
'INTERCEPT' => [
|
'INTERCEPT' => [
|
||||||
|
|
@ -1725,7 +1725,7 @@ class Calculation
|
||||||
],
|
],
|
||||||
'MROUND' => [
|
'MROUND' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'MROUND'],
|
'functionCall' => [MathTrig\Mround::class, 'funcMround'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '2',
|
||||||
],
|
],
|
||||||
'MULTINOMIAL' => [
|
'MULTINOMIAL' => [
|
||||||
|
|
@ -2112,17 +2112,17 @@ class Calculation
|
||||||
],
|
],
|
||||||
'ROUND' => [
|
'ROUND' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'builtinROUND'],
|
'functionCall' => [MathTrig\Round::class, 'builtinROUND'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '2',
|
||||||
],
|
],
|
||||||
'ROUNDDOWN' => [
|
'ROUNDDOWN' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'ROUNDDOWN'],
|
'functionCall' => [MathTrig\RoundDown::class, 'funcRoundDown'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '2',
|
||||||
],
|
],
|
||||||
'ROUNDUP' => [
|
'ROUNDUP' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'ROUNDUP'],
|
'functionCall' => [MathTrig\RoundUp::class, 'funcRoundUp'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '2',
|
||||||
],
|
],
|
||||||
'ROW' => [
|
'ROW' => [
|
||||||
|
|
@ -2474,7 +2474,7 @@ class Calculation
|
||||||
],
|
],
|
||||||
'TRUNC' => [
|
'TRUNC' => [
|
||||||
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
'category' => Category::CATEGORY_MATH_AND_TRIG,
|
||||||
'functionCall' => [MathTrig::class, 'TRUNC'],
|
'functionCall' => [MathTrig\Trunc::class, 'funcTrunc'],
|
||||||
'argumentCount' => '1,2',
|
'argumentCount' => '1,2',
|
||||||
],
|
],
|
||||||
'TTEST' => [
|
'TTEST' => [
|
||||||
|
|
|
||||||
|
|
@ -223,34 +223,18 @@ class MathTrig
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* CEILING(number[,significance])
|
* CEILING(number[,significance])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcCeiling method in the MathTrig\Ceiling class instead
|
||||||
|
*
|
||||||
* @param float $number the number you want to round
|
* @param float $number the number you want to round
|
||||||
* @param float $significance the multiple to which you want to round
|
* @param float $significance the multiple to which you want to round
|
||||||
*
|
*
|
||||||
* @return float|string Rounded Number, or a string containing an error
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function CEILING($number, $significance = null)
|
public static function CEILING($number, $significance = null)
|
||||||
{
|
{
|
||||||
$number = Functions::flattenSingleValue($number);
|
return MathTrig\Ceiling::funcCeiling($number, $significance);
|
||||||
$significance = Functions::flattenSingleValue($significance);
|
|
||||||
|
|
||||||
if (
|
|
||||||
($significance === null) &&
|
|
||||||
(Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC)
|
|
||||||
) {
|
|
||||||
$significance = $number / abs($number);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((is_numeric($number)) && (is_numeric($significance))) {
|
|
||||||
if (($number == 0.0) || ($significance == 0.0)) {
|
|
||||||
return 0.0;
|
|
||||||
} elseif (self::SIGN($number) == self::SIGN($significance)) {
|
|
||||||
return ceil($number / $significance) * $significance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::NAN();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -312,14 +296,19 @@ class MathTrig
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_numeric($number)) {
|
if (is_numeric($number)) {
|
||||||
$significance = 2 * self::SIGN($number);
|
return self::getEven((float) $number);
|
||||||
|
|
||||||
return (int) self::CEILING($number, $significance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Functions::VALUE();
|
return Functions::VALUE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getEven(float $number): int
|
||||||
|
{
|
||||||
|
$significance = 2 * self::returnSign($number);
|
||||||
|
|
||||||
|
return (int) MathTrig\Ceiling::funcCeiling($number, $significance);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FACT.
|
* FACT.
|
||||||
*
|
*
|
||||||
|
|
@ -401,38 +390,18 @@ class MathTrig
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* FLOOR(number[,significance])
|
* FLOOR(number[,significance])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcFloor method in the MathTrig\Floor class instead
|
||||||
|
*
|
||||||
* @param float $number Number to round
|
* @param float $number Number to round
|
||||||
* @param float $significance Significance
|
* @param float $significance Significance
|
||||||
*
|
*
|
||||||
* @return float|string Rounded Number, or a string containing an error
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function FLOOR($number, $significance = null)
|
public static function FLOOR($number, $significance = null)
|
||||||
{
|
{
|
||||||
$number = Functions::flattenSingleValue($number);
|
return MathTrig\Floor::funcFloor($number, $significance);
|
||||||
$significance = Functions::flattenSingleValue($significance);
|
|
||||||
|
|
||||||
if (
|
|
||||||
($significance === null) &&
|
|
||||||
(Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC)
|
|
||||||
) {
|
|
||||||
$significance = $number / abs($number);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((is_numeric($number)) && (is_numeric($significance))) {
|
|
||||||
if ($significance == 0.0) {
|
|
||||||
return Functions::DIV0();
|
|
||||||
} elseif ($number == 0.0) {
|
|
||||||
return 0.0;
|
|
||||||
} elseif (self::SIGN($significance) == 1) {
|
|
||||||
return floor($number / $significance) * $significance;
|
|
||||||
} elseif (self::SIGN($number) == -1 && self::SIGN($significance) == -1) {
|
|
||||||
return floor($number / $significance) * $significance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::NAN();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -443,35 +412,19 @@ class MathTrig
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* FLOOR.MATH(number[,significance[,mode]])
|
* FLOOR.MATH(number[,significance[,mode]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcFloorMath method in the MathTrig\FloorMath class instead
|
||||||
|
*
|
||||||
* @param float $number Number to round
|
* @param float $number Number to round
|
||||||
* @param float $significance Significance
|
* @param float $significance Significance
|
||||||
* @param int $mode direction to round negative numbers
|
* @param int $mode direction to round negative numbers
|
||||||
*
|
*
|
||||||
* @return float|string Rounded Number, or a string containing an error
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function FLOORMATH($number, $significance = null, $mode = 0)
|
public static function FLOORMATH($number, $significance = null, $mode = 0)
|
||||||
{
|
{
|
||||||
$number = Functions::flattenSingleValue($number);
|
return MathTrig\FloorMath::funcFloorMath($number, $significance, $mode);
|
||||||
$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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -482,27 +435,18 @@ class MathTrig
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* FLOOR.PRECISE(number[,significance])
|
* FLOOR.PRECISE(number[,significance])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcFloorPrecise method in the MathTrig\FloorPrecise class instead
|
||||||
|
*
|
||||||
* @param float $number Number to round
|
* @param float $number Number to round
|
||||||
* @param float $significance Significance
|
* @param float $significance Significance
|
||||||
*
|
*
|
||||||
* @return float|string Rounded Number, or a string containing an error
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function FLOORPRECISE($number, $significance = 1)
|
public static function FLOORPRECISE($number, $significance = 1)
|
||||||
{
|
{
|
||||||
$number = Functions::flattenSingleValue($number);
|
return MathTrig\FloorPrecise::funcFloorPrecise($number, $significance);
|
||||||
$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)
|
||||||
|
|
@ -510,6 +454,27 @@ class MathTrig
|
||||||
return $b ? self::evaluateGCD($b, $a % $b) : $a;
|
return $b ? self::evaluateGCD($b, $a % $b) : $a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INT.
|
||||||
|
*
|
||||||
|
* Casts a floating point value to an integer
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* INT(number)
|
||||||
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcInt method in the MathTrig\IntClass class instead
|
||||||
|
*
|
||||||
|
* @param float $number Number to cast to an integer
|
||||||
|
*
|
||||||
|
* @return int|string Integer value, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public static function INT($number)
|
||||||
|
{
|
||||||
|
return MathTrig\IntClass::funcInt($number);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GCD.
|
* GCD.
|
||||||
*
|
*
|
||||||
|
|
@ -544,34 +509,6 @@ class MathTrig
|
||||||
return $gcd;
|
return $gcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* INT.
|
|
||||||
*
|
|
||||||
* Casts a floating point value to an integer
|
|
||||||
*
|
|
||||||
* Excel Function:
|
|
||||||
* INT(number)
|
|
||||||
*
|
|
||||||
* @param float $number Number to cast to an integer
|
|
||||||
*
|
|
||||||
* @return int|string Integer value, or a string containing an error
|
|
||||||
*/
|
|
||||||
public static function INT($number)
|
|
||||||
{
|
|
||||||
$number = Functions::flattenSingleValue($number);
|
|
||||||
|
|
||||||
if ($number === null) {
|
|
||||||
return 0;
|
|
||||||
} elseif (is_bool($number)) {
|
|
||||||
return (int) $number;
|
|
||||||
}
|
|
||||||
if (is_numeric($number)) {
|
|
||||||
return (int) floor($number);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LCM.
|
* LCM.
|
||||||
*
|
*
|
||||||
|
|
@ -847,30 +784,18 @@ class MathTrig
|
||||||
*
|
*
|
||||||
* Rounds a number to the nearest multiple of a specified value
|
* Rounds a number to the nearest multiple of a specified value
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcMround method in the MathTrig\Mround class instead
|
||||||
|
*
|
||||||
* @param float $number Number to round
|
* @param float $number Number to round
|
||||||
* @param int $multiple Multiple to which you want to round $number
|
* @param int $multiple Multiple to which you want to round $number
|
||||||
*
|
*
|
||||||
* @return float|string Rounded Number, or a string containing an error
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function MROUND($number, $multiple)
|
public static function MROUND($number, $multiple)
|
||||||
{
|
{
|
||||||
$number = Functions::flattenSingleValue($number);
|
return MathTrig\Mround::funcMround($number, $multiple);
|
||||||
$multiple = Functions::flattenSingleValue($multiple);
|
|
||||||
|
|
||||||
if ((is_numeric($number)) && (is_numeric($multiple))) {
|
|
||||||
if ($number == 0 || $multiple == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((self::SIGN($number)) == (self::SIGN($multiple))) {
|
|
||||||
$multiplier = 1 / $multiple;
|
|
||||||
|
|
||||||
return round($number * $multiplier) / $multiplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::NAN();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -928,13 +853,16 @@ class MathTrig
|
||||||
} elseif (is_bool($number)) {
|
} elseif (is_bool($number)) {
|
||||||
return 1;
|
return 1;
|
||||||
} elseif (is_numeric($number)) {
|
} elseif (is_numeric($number)) {
|
||||||
$significance = self::SIGN($number);
|
$significance = self::returnSign($number);
|
||||||
if ($significance == 0) {
|
if ($significance == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = self::CEILING($number, $significance);
|
$result = MathTrig\Ceiling::funcCeiling($number, $significance);
|
||||||
if ($result == self::EVEN($result)) {
|
if (is_string($result)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
if ($result == self::getEven((float) $result)) {
|
||||||
$result += $significance;
|
$result += $significance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1104,29 +1032,18 @@ class MathTrig
|
||||||
*
|
*
|
||||||
* Rounds a number up to a specified number of decimal places
|
* Rounds a number up to a specified number of decimal places
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcRoundUp method in the MathTrig\RoundUp class instead
|
||||||
|
*
|
||||||
* @param float $number Number to round
|
* @param float $number Number to round
|
||||||
* @param int $digits Number of digits to which you want to round $number
|
* @param int $digits Number of digits to which you want to round $number
|
||||||
*
|
*
|
||||||
* @return float|string Rounded Number, or a string containing an error
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function ROUNDUP($number, $digits)
|
public static function ROUNDUP($number, $digits)
|
||||||
{
|
{
|
||||||
$number = Functions::flattenSingleValue($number);
|
return MathTrig\RoundUp::funcRoundUp($number, $digits);
|
||||||
$digits = Functions::flattenSingleValue($digits);
|
|
||||||
|
|
||||||
if ((is_numeric($number)) && (is_numeric($digits))) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1134,29 +1051,18 @@ class MathTrig
|
||||||
*
|
*
|
||||||
* Rounds a number down to a specified number of decimal places
|
* Rounds a number down to a specified number of decimal places
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcRoundDown method in the MathTrig\RoundDown class instead
|
||||||
|
*
|
||||||
* @param float $number Number to round
|
* @param float $number Number to round
|
||||||
* @param int $digits Number of digits to which you want to round $number
|
* @param int $digits Number of digits to which you want to round $number
|
||||||
*
|
*
|
||||||
* @return float|string Rounded Number, or a string containing an error
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function ROUNDDOWN($number, $digits)
|
public static function ROUNDDOWN($number, $digits)
|
||||||
{
|
{
|
||||||
$number = Functions::flattenSingleValue($number);
|
return MathTrig\RoundDown::funcRoundDown($number, $digits);
|
||||||
$digits = Functions::flattenSingleValue($digits);
|
|
||||||
|
|
||||||
if ((is_numeric($number)) && (is_numeric($digits))) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1215,16 +1121,17 @@ class MathTrig
|
||||||
return (int) $number;
|
return (int) $number;
|
||||||
}
|
}
|
||||||
if (is_numeric($number)) {
|
if (is_numeric($number)) {
|
||||||
if ($number == 0.0) {
|
return self::returnSign($number);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $number / abs($number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Functions::VALUE();
|
return Functions::VALUE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function returnSign(float $number): int
|
||||||
|
{
|
||||||
|
return $number ? (($number > 0) ? 1 : -1) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQRTPI.
|
* SQRTPI.
|
||||||
*
|
*
|
||||||
|
|
@ -1628,30 +1535,18 @@ class MathTrig
|
||||||
*
|
*
|
||||||
* Truncates value to the number of fractional digits by number_digits.
|
* Truncates value to the number of fractional digits by number_digits.
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the funcTrunc method in the MathTrig\Trunc class instead
|
||||||
|
*
|
||||||
* @param float $value
|
* @param float $value
|
||||||
* @param int $digits
|
* @param int $digits
|
||||||
*
|
*
|
||||||
* @return float|string Truncated value, or a string containing an error
|
* @return float|string Truncated value, or a string containing an error
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function TRUNC($value = 0, $digits = 0)
|
public static function TRUNC($value = 0, $digits = 0)
|
||||||
{
|
{
|
||||||
$value = Functions::flattenSingleValue($value);
|
return MathTrig\Trunc::funcTrunc($value, $digits);
|
||||||
$digits = Functions::flattenSingleValue($digits);
|
|
||||||
|
|
||||||
// Validate parameters
|
|
||||||
if ((!is_numeric($value)) || (!is_numeric($digits))) {
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
|
||||||
$digits = floor($digits);
|
|
||||||
|
|
||||||
// Truncate
|
|
||||||
$adjust = 10 ** $digits;
|
|
||||||
|
|
||||||
if (($digits > 0) && (rtrim((int) ((abs($value) - abs((int) $value)) * $adjust), '0') < $adjust / 10)) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((int) ($value * $adjust)) / $adjust;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1845,20 +1740,18 @@ class MathTrig
|
||||||
*
|
*
|
||||||
* Returns the result of builtin function round after validating args.
|
* Returns the result of builtin function round after validating args.
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the builtinRound method in the MathTrig\Round class instead
|
||||||
|
*
|
||||||
* @param mixed $number Should be numeric
|
* @param mixed $number Should be numeric
|
||||||
* @param mixed $precision Should be int
|
* @param mixed $precision Should be int
|
||||||
*
|
*
|
||||||
* @return float|string Rounded number
|
* @return float|string Rounded number
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public static function builtinROUND($number, $precision)
|
public static function builtinROUND($number, $precision)
|
||||||
{
|
{
|
||||||
$number = Functions::flattenSingleValue($number);
|
return MathTrig\Round::builtinRound($number, $precision);
|
||||||
|
|
||||||
if (!is_numeric($number) || !is_numeric($precision)) {
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
|
||||||
|
|
||||||
return round($number, $precision);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2245,4 +2138,19 @@ class MathTrig
|
||||||
{
|
{
|
||||||
return abs($number) < 1.0E-12;
|
return abs($number) < 1.0E-12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Many functions accept null/false/true argument treated as 0/0/1.
|
||||||
|
*
|
||||||
|
* @param mixed $number
|
||||||
|
*/
|
||||||
|
public static function nullFalseTrueToNumber(&$number): void
|
||||||
|
{
|
||||||
|
$number = Functions::flattenSingleValue($number);
|
||||||
|
if ($number === null) {
|
||||||
|
$number = 0;
|
||||||
|
} elseif (is_bool($number)) {
|
||||||
|
$number = (int) $number;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class Ceiling
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* CEILING.
|
||||||
|
*
|
||||||
|
* Returns number rounded up, away from zero, to the nearest multiple of significance.
|
||||||
|
* For example, if you want to avoid using pennies in your prices and your product is
|
||||||
|
* priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the
|
||||||
|
* nearest nickel.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* CEILING(number[,significance])
|
||||||
|
*
|
||||||
|
* @param float $number the number you want the ceiling
|
||||||
|
* @param float $significance the multiple to which you want to round
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function funcCeiling($number, $significance = null)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
$significance = Functions::flattenSingleValue($significance);
|
||||||
|
|
||||||
|
if ($significance === null) {
|
||||||
|
self::floorCheck1Arg();
|
||||||
|
$significance = ((float) $number < 0) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((is_numeric($number)) && (is_numeric($significance))) {
|
||||||
|
return self::argumentsOk((float) $number, (float) $significance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid Scrutinizer problems concerning complexity.
|
||||||
|
*
|
||||||
|
* @return float|string
|
||||||
|
*/
|
||||||
|
private static function argumentsOk(float $number, float $significance)
|
||||||
|
{
|
||||||
|
if (empty($number * $significance)) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (MathTrig::returnSign($number) == MathTrig::returnSign($significance)) {
|
||||||
|
return ceil($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::NAN();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function floorCheck1Arg(): void
|
||||||
|
{
|
||||||
|
$compatibility = Functions::getCompatibilityMode();
|
||||||
|
if ($compatibility === Functions::COMPATIBILITY_EXCEL) {
|
||||||
|
throw new Exception('Excel requires 2 arguments for CEILING');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class CeilingMath
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* CEILING.MATH.
|
||||||
|
*
|
||||||
|
* Round a number down to the nearest integer or to the nearest multiple of significance.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* CEILING.MATH(number[,significance[,mode]])
|
||||||
|
*
|
||||||
|
* @param mixed $number Number to round
|
||||||
|
* @param mixed $significance Significance
|
||||||
|
* @param int $mode direction to round negative numbers
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function funcCeilingMath($number, $significance = null, $mode = 0)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
$significance = Functions::flattenSingleValue($significance);
|
||||||
|
$mode = Functions::flattenSingleValue($mode);
|
||||||
|
|
||||||
|
if ($significance === null) {
|
||||||
|
$significance = ((float) $number < 0) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_numeric($number) && is_numeric($significance) && is_numeric($mode)) {
|
||||||
|
if (empty($significance * $number)) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (self::ceilingMathTest((float) $significance, (float) $number, (int) $mode)) {
|
||||||
|
return floor($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ceil($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Let CEILINGMATH complexity pass Scrutinizer.
|
||||||
|
*/
|
||||||
|
private static function ceilingMathTest(float $significance, float $number, int $mode): bool
|
||||||
|
{
|
||||||
|
return ((float) $significance < 0) || ((float) $number < 0 && !empty($mode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class CeilingPrecise
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* CEILING.PRECISE.
|
||||||
|
*
|
||||||
|
* Rounds number up, away from zero, to the nearest multiple of significance.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* CEILING.PRECISE(number[,significance])
|
||||||
|
*
|
||||||
|
* @param mixed $number the number you want to round
|
||||||
|
* @param float $significance the multiple to which you want to round
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function funcCeilingPrecise($number, $significance = 1)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
$significance = Functions::flattenSingleValue($significance);
|
||||||
|
|
||||||
|
if ((is_numeric($number)) && (is_numeric($significance))) {
|
||||||
|
if ($significance == 0.0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
$result = $number / abs($significance);
|
||||||
|
|
||||||
|
return ceil($result) * $significance * (($significance < 0) ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class Floor
|
||||||
|
{
|
||||||
|
private static function floorCheck1Arg(): void
|
||||||
|
{
|
||||||
|
$compatibility = Functions::getCompatibilityMode();
|
||||||
|
if ($compatibility === Functions::COMPATIBILITY_EXCEL) {
|
||||||
|
throw new Exception('Excel requires 2 arguments for FLOOR');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FLOOR.
|
||||||
|
*
|
||||||
|
* Rounds number down, toward zero, to the nearest multiple of significance.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* FLOOR(number[,significance])
|
||||||
|
*
|
||||||
|
* @param float $number Number to round
|
||||||
|
* @param float $significance Significance
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function funcFloor($number, $significance = null)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
$significance = Functions::flattenSingleValue($significance);
|
||||||
|
|
||||||
|
if ($significance === null) {
|
||||||
|
self::floorCheck1Arg();
|
||||||
|
$significance = MathTrig::returnSign((float) $number);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((is_numeric($number)) && (is_numeric($significance))) {
|
||||||
|
return self::argumentsOk((float) $number, (float) $significance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid Scrutinizer problems concerning complexity.
|
||||||
|
*
|
||||||
|
* @return float|string
|
||||||
|
*/
|
||||||
|
private static function argumentsOk(float $number, float $significance)
|
||||||
|
{
|
||||||
|
if ($significance == 0.0) {
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
if ($number == 0.0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (MathTrig::returnSign($significance) == 1) {
|
||||||
|
return floor($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
if (MathTrig::returnSign($number) == -1 && MathTrig::returnSign($significance) == -1) {
|
||||||
|
return floor($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::NAN();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class FloorMath
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* FLOOR.MATH.
|
||||||
|
*
|
||||||
|
* Round a number down to the nearest integer or to the nearest multiple of significance.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* FLOOR.MATH(number[,significance[,mode]])
|
||||||
|
*
|
||||||
|
* @param mixed $number Number to round
|
||||||
|
* @param mixed $significance Significance
|
||||||
|
* @param mixed $mode direction to round negative numbers
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function funcFloorMath($number, $significance = null, $mode = 0)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
$significance = Functions::flattenSingleValue($significance);
|
||||||
|
$mode = Functions::flattenSingleValue($mode);
|
||||||
|
|
||||||
|
if ($significance === null) {
|
||||||
|
$significance = ((float) $number < 0) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_numeric($number) && is_numeric($significance) && is_numeric($mode)) {
|
||||||
|
return self::argsOk((float) $number, (float) $significance, (int) $mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid Scrutinizer complexity problems.
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
private static function argsOk(float $number, float $significance, int $mode)
|
||||||
|
{
|
||||||
|
if (!$significance) {
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
if (!$number) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (self::floorMathTest($number, $significance, $mode)) {
|
||||||
|
return ceil($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return floor($number / $significance) * $significance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Let FLOORMATH complexity pass Scrutinizer.
|
||||||
|
*/
|
||||||
|
private static function floorMathTest(float $number, float $significance, int $mode): bool
|
||||||
|
{
|
||||||
|
return mathTrig::returnSign($significance) == -1 || (mathTrig::returnSign($number) == -1 && !empty($mode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class FloorPrecise
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* FLOOR.PRECISE.
|
||||||
|
*
|
||||||
|
* Rounds number down, toward zero, to the nearest multiple of significance.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* FLOOR.PRECISE(number[,significance])
|
||||||
|
*
|
||||||
|
* @param float $number Number to round
|
||||||
|
* @param float $significance Significance
|
||||||
|
*
|
||||||
|
* @return float|string Rounded Number, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function funcFloorPrecise($number, $significance = 1)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
$significance = Functions::flattenSingleValue($significance);
|
||||||
|
|
||||||
|
if ((is_numeric($number)) && (is_numeric($significance))) {
|
||||||
|
return self::argumentsOk((float) $number, (float) $significance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid Scrutinizer problems concerning complexity.
|
||||||
|
*
|
||||||
|
* @return float|string
|
||||||
|
*/
|
||||||
|
private static function argumentsOk(float $number, float $significance)
|
||||||
|
{
|
||||||
|
if ($significance == 0.0) {
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
if ($number == 0.0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return floor($number / abs($significance)) * abs($significance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class IntClass
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* INT.
|
||||||
|
*
|
||||||
|
* Casts a floating point value to an integer
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* INT(number)
|
||||||
|
*
|
||||||
|
* @param float $number Number to cast to an integer
|
||||||
|
*
|
||||||
|
* @return int|string Integer value, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function funcInt($number)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
if (is_numeric($number)) {
|
||||||
|
return (int) floor($number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class Mround
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* MROUND.
|
||||||
|
*
|
||||||
|
* Rounds a number to the nearest multiple of a specified value
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
public static function funcMround($number, $multiple)
|
||||||
|
{
|
||||||
|
$number = Functions::flattenSingleValue($number);
|
||||||
|
$number = $number ?? 0;
|
||||||
|
|
||||||
|
$multiple = Functions::flattenSingleValue($multiple);
|
||||||
|
|
||||||
|
if ((is_numeric($number)) && (is_numeric($multiple))) {
|
||||||
|
if ($number == 0 || $multiple == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((MathTrig::SIGN($number)) == (MathTrig::SIGN($multiple))) {
|
||||||
|
$multiplier = 1 / $multiple;
|
||||||
|
|
||||||
|
return round($number * $multiplier) / $multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::NAN();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class Round
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ROUND.
|
||||||
|
*
|
||||||
|
* Returns the result of builtin function round after validating args.
|
||||||
|
*
|
||||||
|
* @param mixed $number Should be numeric
|
||||||
|
* @param mixed $precision Should be int
|
||||||
|
*
|
||||||
|
* @return float|string Rounded number
|
||||||
|
*/
|
||||||
|
public static function builtinROUND($number, $precision)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
|
||||||
|
if (!is_numeric($number) || !is_numeric($precision)) {
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
return round($number, $precision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class RoundDown
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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 funcRoundDown($number, $digits)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
$digits = Functions::flattenSingleValue($digits);
|
||||||
|
|
||||||
|
if ((is_numeric($number)) && (is_numeric($digits))) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class RoundUp
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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 funcRoundUp($number, $digits)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($number);
|
||||||
|
$digits = Functions::flattenSingleValue($digits);
|
||||||
|
|
||||||
|
if ((is_numeric($number)) && (is_numeric($digits))) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class Trunc
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* TRUNC.
|
||||||
|
*
|
||||||
|
* Truncates value to the number of fractional digits by number_digits.
|
||||||
|
*
|
||||||
|
* @param float $value
|
||||||
|
* @param int $digits
|
||||||
|
*
|
||||||
|
* @return float|string Truncated value, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function funcTrunc($value = 0, $digits = 0)
|
||||||
|
{
|
||||||
|
MathTrig::nullFalseTrueToNumber($value);
|
||||||
|
$digits = Functions::flattenSingleValue($digits);
|
||||||
|
|
||||||
|
// Validate parameters
|
||||||
|
if ((!is_numeric($value)) || (!is_numeric($digits))) {
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
$digits = floor($digits);
|
||||||
|
|
||||||
|
// Truncate
|
||||||
|
$adjust = 10 ** $digits;
|
||||||
|
|
||||||
|
if (($digits > 0) && (rtrim((int) ((abs($value) - abs((int) $value)) * $adjust), '0') < $adjust / 10)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((int) ($value * $adjust)) / $adjust;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -172,7 +172,7 @@ class TextData
|
||||||
if ($value < 0) {
|
if ($value < 0) {
|
||||||
$round = 0 - $round;
|
$round = 0 - $round;
|
||||||
}
|
}
|
||||||
$value = MathTrig::MROUND($value, $round);
|
$value = MathTrig\Mround::funcMround($value, $round);
|
||||||
}
|
}
|
||||||
$mask = "$mask;($mask)";
|
$mask = "$mask;($mask)";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ BITOR
|
||||||
BITRSHIFT
|
BITRSHIFT
|
||||||
BITXOR
|
BITXOR
|
||||||
CEILING
|
CEILING
|
||||||
|
CEILING.MATH
|
||||||
|
CEILING.PRECISE
|
||||||
CELL
|
CELL
|
||||||
CHAR
|
CHAR
|
||||||
CHIDIST
|
CHIDIST
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ class Xlfn
|
||||||
. '|beta[.]inv'
|
. '|beta[.]inv'
|
||||||
. '|binom[.]dist'
|
. '|binom[.]dist'
|
||||||
. '|binom[.]inv'
|
. '|binom[.]inv'
|
||||||
|
. '|ceiling[.]precise'
|
||||||
. '|chisq[.]dist'
|
. '|chisq[.]dist'
|
||||||
. '|chisq[.]dist[.]rt'
|
. '|chisq[.]dist[.]rt'
|
||||||
. '|chisq[.]inv'
|
. '|chisq[.]inv'
|
||||||
|
|
@ -27,6 +28,7 @@ class Xlfn
|
||||||
. '|f[.]inv'
|
. '|f[.]inv'
|
||||||
. '|f[.]inv[.]rt'
|
. '|f[.]inv[.]rt'
|
||||||
. '|f[.]test'
|
. '|f[.]test'
|
||||||
|
. '|floor[.]precise'
|
||||||
. '|gamma[.]dist'
|
. '|gamma[.]dist'
|
||||||
. '|gamma[.]inv'
|
. '|gamma[.]inv'
|
||||||
. '|gammaln[.]precise'
|
. '|gammaln[.]precise'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class CeilingMathTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerCEILINGMATH
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param string $formula
|
||||||
|
*/
|
||||||
|
public function testCEILINGMATH($expectedResult, $formula): void
|
||||||
|
{
|
||||||
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=CEILING.MATH($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerCEILINGMATH()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/MathTrig/CEILINGMATH.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class CeilingPreciseTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerFLOORPRECISE
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param string $formula
|
||||||
|
*/
|
||||||
|
public function testCEILINGPRECISE($expectedResult, $formula): void
|
||||||
|
{
|
||||||
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=CEILING.PRECISE($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerFLOORPRECISE()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/MathTrig/CEILINGPRECISE.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,25 +2,45 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class CeilingTest extends TestCase
|
class CeilingTest extends TestCase
|
||||||
{
|
{
|
||||||
|
private $compatibilityMode;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
$this->compatibilityMode = Functions::getCompatibilityMode();
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode($this->compatibilityMode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerCEILING
|
* @dataProvider providerCEILING
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param string $formula
|
||||||
*/
|
*/
|
||||||
public function testCEILING($expectedResult, ...$args): void
|
public function testCEILING($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::CEILING(...$args);
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=CEILING($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,4 +48,35 @@ class CeilingTest extends TestCase
|
||||||
{
|
{
|
||||||
return require 'tests/data/Calculation/MathTrig/CEILING.php';
|
return require 'tests/data/Calculation/MathTrig/CEILING.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCEILINGGnumeric1Arg(): void
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->getCell('A1')->setValue('=CEILING(5.1)');
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta(6, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCELINGOpenOffice1Arg(): void
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->getCell('A1')->setValue('=CEILING(5.1)');
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta(6, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFLOORExcel1Arg(): void
|
||||||
|
{
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||||
|
$sheet->getCell('A1')->setValue('=CEILING(5.1)');
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta(6, $result, 1E-12);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,31 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class FloorMathTest extends TestCase
|
class FloorMathTest extends TestCase
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerFLOORMATH
|
* @dataProvider providerFLOORMATH
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param string $formula
|
||||||
*/
|
*/
|
||||||
public function testFLOORMATH($expectedResult, ...$args): void
|
public function testFLOORMATH($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::FLOORMATH(...$args);
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=FLOOR.MATH($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,31 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class FloorPreciseTest extends TestCase
|
class FloorPreciseTest extends TestCase
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerFLOORPRECISE
|
* @dataProvider providerFLOORPRECISE
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param string $formula
|
||||||
*/
|
*/
|
||||||
public function testFLOOR($expectedResult, ...$args): void
|
public function testFLOORPRECISE($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::FLOORPRECISE(...$args);
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=FLOOR.PRECISE($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,45 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class FloorTest extends TestCase
|
class FloorTest extends TestCase
|
||||||
{
|
{
|
||||||
|
private $compatibilityMode;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
|
$this->compatibilityMode = Functions::getCompatibilityMode();
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode($this->compatibilityMode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerFLOOR
|
* @dataProvider providerFLOOR
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param string $formula
|
||||||
*/
|
*/
|
||||||
public function testFLOOR($expectedResult, ...$args): void
|
public function testFLOOR($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::FLOOR(...$args);
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=FLOOR($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,4 +48,35 @@ class FloorTest extends TestCase
|
||||||
{
|
{
|
||||||
return require 'tests/data/Calculation/MathTrig/FLOOR.php';
|
return require 'tests/data/Calculation/MathTrig/FLOOR.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFLOORGnumeric1Arg(): void
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->getCell('A1')->setValue('=FLOOR(5.1)');
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta(5, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFLOOROpenOffice1Arg(): void
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->getCell('A1')->setValue('=FLOOR(5.1)');
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta(5, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFLOORExcel1Arg(): void
|
||||||
|
{
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||||
|
$sheet->getCell('A1')->setValue('=FLOOR(5.1)');
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta(5, $result, 1E-12);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,32 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class IntTest extends TestCase
|
class IntTest extends TestCase
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerINT
|
* @dataProvider providerINT
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
* @param $value
|
* @param string $formula
|
||||||
*/
|
*/
|
||||||
public function testINT($expectedResult, $value): void
|
public function testINT($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::INT($value);
|
if ($expectedResult === 'exception') {
|
||||||
self::assertEquals($expectedResult, $result);
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=INT($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function providerINT()
|
public function providerINT()
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,31 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class MRoundTest extends TestCase
|
class MRoundTest extends TestCase
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerMROUND
|
* @dataProvider providerMROUND
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $formula
|
||||||
*/
|
*/
|
||||||
public function testMROUND($expectedResult, ...$args): void
|
public function testMROUND($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::MROUND(...$args);
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=MROUND($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
// Sanity tests for functions which have been moved out of MathTrig
|
||||||
|
// to their own classes. A deprecated version remains in MathTrig;
|
||||||
|
// this class contains cursory tests to ensure that those work properly.
|
||||||
|
// If Scrutinizer fails the PR because of these deprecations, I will
|
||||||
|
// remove this class from the PR.
|
||||||
|
|
||||||
|
class MovedFunctionsTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testMovedFunctions(): void
|
||||||
|
{
|
||||||
|
self::assertEquals(-6, MathTrig::CEILING(-4.5, -2));
|
||||||
|
self::assertEquals(-6, MathTrig::FLOOR(-4.5, 2));
|
||||||
|
self::assertEquals(0.23, MathTrig::FLOORMATH(0.234, 0.01));
|
||||||
|
self::assertEquals(-4, MathTrig::FLOORPRECISE(-2.5, 2));
|
||||||
|
self::assertEquals(-9, MathTrig::INT(-8.3));
|
||||||
|
self::assertEquals(6, MathTrig::MROUND(7.3, 3));
|
||||||
|
self::assertEquals(3.3, MathTrig::builtinROUND(3.27, 1));
|
||||||
|
self::assertEquals(662, MathTrig::ROUNDDOWN(662.79, 0));
|
||||||
|
self::assertEquals(663, MathTrig::ROUNDUP(662.79, 0));
|
||||||
|
self::assertEquals(70, MathTrig::TRUNC(79.2, -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,29 +2,35 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class RoundDownTest extends TestCase
|
class RoundDownTest extends TestCase
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerROUNDDOWN
|
* @dataProvider providerRoundDown
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $formula
|
||||||
*/
|
*/
|
||||||
public function testROUNDDOWN($expectedResult, ...$args): void
|
public function testRoundDown($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::ROUNDDOWN(...$args);
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=ROUNDDOWN($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function providerROUNDDOWN()
|
public function providerRoundDown()
|
||||||
{
|
{
|
||||||
return require 'tests/data/Calculation/MathTrig/ROUNDDOWN.php';
|
return require 'tests/data/Calculation/MathTrig/ROUNDDOWN.php';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,23 +12,20 @@ class RoundTest extends TestCase
|
||||||
* @dataProvider providerRound
|
* @dataProvider providerRound
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
* @param mixed $val
|
* @param mixed $formula
|
||||||
* @param mixed $precision
|
|
||||||
*/
|
*/
|
||||||
public function testRound($expectedResult, $val = null, $precision = null): void
|
public function testRound($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
if ($val === null) {
|
if ($expectedResult === 'exception') {
|
||||||
$this->expectException(CalcExp::class);
|
$this->expectException(CalcExp::class);
|
||||||
$formula = '=ROUND()';
|
|
||||||
} elseif ($precision === null) {
|
|
||||||
$this->expectException(CalcExp::class);
|
|
||||||
$formula = "=ROUND($val)";
|
|
||||||
} else {
|
|
||||||
$formula = "=ROUND($val, $precision)";
|
|
||||||
}
|
}
|
||||||
$spreadsheet = new Spreadsheet();
|
$spreadsheet = new Spreadsheet();
|
||||||
$sheet = $spreadsheet->getActiveSheet();
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
$sheet->getCell('A1')->setValue($formula);
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=ROUND($formula)");
|
||||||
$result = $sheet->getCell('A1')->getCalculatedValue();
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,35 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class RoundUpTest extends TestCase
|
class RoundUpTest extends TestCase
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerROUNDUP
|
* @dataProvider providerRoundUp
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $formula
|
||||||
*/
|
*/
|
||||||
public function testROUNDUP($expectedResult, ...$args): void
|
public function testRoundUp($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::ROUNDUP(...$args);
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=ROUNDUP($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function providerROUNDUP()
|
public function providerRoundUp()
|
||||||
{
|
{
|
||||||
return require 'tests/data/Calculation/MathTrig/ROUNDUP.php';
|
return require 'tests/data/Calculation/MathTrig/ROUNDUP.php';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,31 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class TruncTest extends TestCase
|
class TruncTest extends TestCase
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerTRUNC
|
* @dataProvider providerTRUNC
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param string $formula
|
||||||
*/
|
*/
|
||||||
public function testTRUNC($expectedResult, ...$args): void
|
public function testTRUNC($expectedResult, $formula): void
|
||||||
{
|
{
|
||||||
$result = MathTrig::TRUNC(...$args);
|
if ($expectedResult === 'exception') {
|
||||||
|
$this->expectException(CalcExp::class);
|
||||||
|
}
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$sheet->setCellValue('A2', 1.3);
|
||||||
|
$sheet->setCellValue('A3', 2.7);
|
||||||
|
$sheet->setCellValue('A4', -3.8);
|
||||||
|
$sheet->setCellValue('A5', -5.2);
|
||||||
|
$sheet->getCell('A1')->setValue("=TRUNC($formula)");
|
||||||
|
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,104 +1,34 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// number, significance, result
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[3.0, '2.5, 1'],
|
||||||
3.0,
|
[-4.0, '-2.5, -2'],
|
||||||
2.5,
|
[1.5, '1.5, 0.1'],
|
||||||
1,
|
[0.24, '0.234, 0.01'],
|
||||||
],
|
[-2.4, '-2.341, -0.1'],
|
||||||
[
|
[0.0, '8, 0'],
|
||||||
-4.0,
|
[9.0, '8, 1.5'],
|
||||||
-2.5,
|
['#NUM!', '8, -1.5'],
|
||||||
-2,
|
['#NUM!', '-8, 1.5'],
|
||||||
],
|
[-9.0, '-8, -1.5'],
|
||||||
[
|
[8.3, '8.26, 0.05'],
|
||||||
1.5,
|
[2.35, '2.341, 0.05'],
|
||||||
1.5,
|
['#VALUE!', '123.456, "abc"'],
|
||||||
0.10000000000000001,
|
['exception', '123.456'],
|
||||||
],
|
['#VALUE!', '"PhpSpreadsheet", 1'],
|
||||||
[
|
['exception', '"PhpSpreadsheet"'],
|
||||||
0.23999999999999999,
|
[211.0, '210.67, 1'],
|
||||||
0.23400000000000001,
|
[210.70, '210.67, 0.05'],
|
||||||
0.01,
|
[210.65, '210.63, 0.05'],
|
||||||
],
|
[4.0, '2.98, 2'],
|
||||||
[
|
['#NUM!', '-2.98, 2'],
|
||||||
-2.3999999999999999,
|
[-5.0, '-4.5, -1'],
|
||||||
-2.3410000000000002,
|
[0, ',1'],
|
||||||
-0.10000000000000001,
|
[0, 'false,1'],
|
||||||
],
|
[1, 'true,1'],
|
||||||
[
|
['#VALUE!', '"", 1'],
|
||||||
0.0,
|
[2, 'A2, 1'],
|
||||||
8,
|
[3, 'A3, 1'],
|
||||||
0,
|
[-4, 'A4, -1'],
|
||||||
],
|
[-6, 'A5, -1'],
|
||||||
[
|
|
||||||
9.0,
|
|
||||||
8,
|
|
||||||
1.5,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#NUM!',
|
|
||||||
8,
|
|
||||||
-1.5,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#NUM!',
|
|
||||||
-8,
|
|
||||||
1.5,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-9.0,
|
|
||||||
-8,
|
|
||||||
-1.5,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
8.3000000000000007,
|
|
||||||
8.2599999999999998,
|
|
||||||
0.050000000000000003,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
2.3500000000000001,
|
|
||||||
2.3410000000000002,
|
|
||||||
0.050000000000000003,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
123.456,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
'PhpSpreadsheet',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
211.0,
|
|
||||||
210.66999999999999,
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
210.69999999999999,
|
|
||||||
210.66999999999999,
|
|
||||||
0.050000000000000003,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
210.65000000000001,
|
|
||||||
210.63,
|
|
||||||
0.050000000000000003,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
4.0,
|
|
||||||
2.98,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#NUM!',
|
|
||||||
-2.98,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-5.0,
|
|
||||||
-4.5,
|
|
||||||
-1,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[3, '2.5, 1'],
|
||||||
|
[-2, '"-2.5", "-2"'],
|
||||||
|
[-2, '-2.5, 2'],
|
||||||
|
[4, '2.5, -2'],
|
||||||
|
[0.0, '0.0, 1'],
|
||||||
|
['0', '123.456, 0'],
|
||||||
|
[1.5, '1.5, 0.1'],
|
||||||
|
[0.24, '0.234, 0.01'],
|
||||||
|
[124, '123.456'],
|
||||||
|
['#VALUE!', '"ABC"'],
|
||||||
|
[18, '17, 3'],
|
||||||
|
[20, '19, 4'],
|
||||||
|
[25, '24.3, 5'],
|
||||||
|
[7, '6.7, 1'],
|
||||||
|
[-8, '-8.1, 2'],
|
||||||
|
[-6, '-5.5, 2, -1'],
|
||||||
|
[-6, '-5.5, 2, 1'],
|
||||||
|
[-4, '-5.5, 2, 0'],
|
||||||
|
['exception', ''],
|
||||||
|
[0, ','],
|
||||||
|
[0, ', 2'],
|
||||||
|
[0, 'false'],
|
||||||
|
[1, 'true'],
|
||||||
|
['#VALUE!', '"", 2'],
|
||||||
|
[2, 'A2'],
|
||||||
|
[3, 'A3'],
|
||||||
|
[-3, 'A4'],
|
||||||
|
[-5, 'A5'],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[3, '2.5, 1'],
|
||||||
|
[-2, '-2.5, -2'],
|
||||||
|
[-2, '-2.5, 2'],
|
||||||
|
[4, '2.5, -2'],
|
||||||
|
[0.0, '0.0, 1'],
|
||||||
|
[0.0, '123.456, 0'],
|
||||||
|
[1.5, '1.5, 0.1'],
|
||||||
|
[0.24, '0.234, 0.01'],
|
||||||
|
[124, '123.456, 1'],
|
||||||
|
['#VALUE!', '"ABC"'],
|
||||||
|
[18, '17, 3'],
|
||||||
|
[20, '19, 4'],
|
||||||
|
['exception', ''],
|
||||||
|
['#VALUE!', '25, "ABC"'],
|
||||||
|
[0, ',1'],
|
||||||
|
[0, 'false,1'],
|
||||||
|
[1, 'true,1'],
|
||||||
|
['#VALUE!', '"", 1'],
|
||||||
|
[2, 'A2, 1'],
|
||||||
|
[3, 'A3, 1'],
|
||||||
|
[-3, 'A4, 1'],
|
||||||
|
[-5, 'A5, 1'],
|
||||||
|
];
|
||||||
|
|
@ -1,62 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[2, '2.5, 1'],
|
||||||
2,
|
[-2, '-2.5, -2'],
|
||||||
2.5,
|
[-4, '-2.5, 2'],
|
||||||
1,
|
[0.0, '0.0, 1'],
|
||||||
],
|
['#NUM!', '2.5, -2'],
|
||||||
[
|
['#DIV/0!', '123.456, 0'],
|
||||||
-2,
|
[1.5, '1.5, 0.1'],
|
||||||
-2.5,
|
[0.23, '0.234, 0.01'],
|
||||||
-2,
|
['exception', '123.456'],
|
||||||
],
|
['#VALUE!', '"ABC", 1'],
|
||||||
[
|
[15, '"17", "3"'],
|
||||||
-4,
|
[16, '19, 4'],
|
||||||
-2.5,
|
[0, ',1'],
|
||||||
2,
|
[0, 'false,1'],
|
||||||
],
|
[1, 'true,1'],
|
||||||
[
|
['#VALUE!', '"", 1'],
|
||||||
0.0,
|
[1, 'A2, 1'],
|
||||||
0.0,
|
[2, 'A3, 1'],
|
||||||
1,
|
[-4, 'A4, 1'],
|
||||||
],
|
[-6, 'A5, 1'],
|
||||||
[
|
|
||||||
'#NUM!',
|
|
||||||
2.5,
|
|
||||||
-2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#DIV/0!',
|
|
||||||
123.456,
|
|
||||||
0,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1.5,
|
|
||||||
1.5,
|
|
||||||
0.10000000000000001,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
0.23000000000000001,
|
|
||||||
0.23400000000000001,
|
|
||||||
0.01,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
123.456,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
'ABC',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
15,
|
|
||||||
17,
|
|
||||||
3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
16,
|
|
||||||
19,
|
|
||||||
4,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,94 +1,32 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[2, '2.5, 1'],
|
||||||
2,
|
[-4, '"-2.5", "-2"'],
|
||||||
2.5,
|
[-4, '-2.5, 2'],
|
||||||
1,
|
[2, '2.5, -2'],
|
||||||
],
|
[0.0, '0.0, 1'],
|
||||||
[
|
['#DIV/0!', '123.456, 0'],
|
||||||
-4,
|
[1.5, '1.5, 0.1'],
|
||||||
-2.5,
|
[0.23, '0.234, 0.01'],
|
||||||
-2,
|
[123, '123.456'],
|
||||||
],
|
['#VALUE!', '"ABC"'],
|
||||||
[
|
[15, '17, 3'],
|
||||||
-4,
|
[16, '19, 4'],
|
||||||
-2.5,
|
[20, '24.3, 5'],
|
||||||
2,
|
[6, '6.7, 1'],
|
||||||
],
|
[-10, '-8.1, 2'],
|
||||||
[
|
[-4, '-5.5, 2, -1'],
|
||||||
2,
|
[-4, '-5.5, 2, 1'],
|
||||||
2.5,
|
[-6, '-5.5, 2, 0'],
|
||||||
-2,
|
['exception', ''],
|
||||||
],
|
[0, ','],
|
||||||
[
|
[0, ', 2'],
|
||||||
0.0,
|
[0, 'false'],
|
||||||
0.0,
|
[1, 'true'],
|
||||||
1,
|
['#VALUE!', '"", 2'],
|
||||||
],
|
[1, 'A2'],
|
||||||
[
|
[2, 'A3'],
|
||||||
'#DIV/0!',
|
[-4, 'A4'],
|
||||||
123.456,
|
[-6, 'A5'],
|
||||||
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,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,26 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[2, '2.5, 1'],
|
||||||
2,
|
[-4, '-2.5, -2'],
|
||||||
2.5,
|
[-4, '-2.5, 2'],
|
||||||
1,
|
[2, '2.5, -2'],
|
||||||
],
|
[0.0, '0.0, 1'],
|
||||||
[
|
['#DIV/0!', '123.456, 0'],
|
||||||
-4,
|
[1.5, '1.5, 0.1'],
|
||||||
-2.5,
|
[0.23, '0.234, 0.01'],
|
||||||
-2,
|
[123, '123.456'],
|
||||||
],
|
['#VALUE!', '"ABC"'],
|
||||||
[
|
[15, '17, 3'],
|
||||||
-4,
|
[16, '19, 4'],
|
||||||
-2.5,
|
['exception', ''],
|
||||||
2,
|
['#VALUE!', '25, "ABC"'],
|
||||||
],
|
[0, ',1'],
|
||||||
[
|
[0, 'false,1'],
|
||||||
2,
|
[1, 'true,1'],
|
||||||
2.5,
|
['#VALUE!', '"", 1'],
|
||||||
-2,
|
[1, 'A2, 1'],
|
||||||
],
|
[2, 'A3, 1'],
|
||||||
[
|
[-4, 'A4, 1'],
|
||||||
0.0,
|
[-6, 'A5, 1'],
|
||||||
0.0,
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#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,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,80 +1,29 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
['exception', ''],
|
||||||
0,
|
[5, '5.4'],
|
||||||
null,
|
[-6, '-5.4'],
|
||||||
],
|
[-4, '-3.2'],
|
||||||
[
|
[1, '"1.5"'],
|
||||||
5,
|
[0, '0.1'],
|
||||||
5.4000000000000004,
|
[-1, '-0.1'],
|
||||||
],
|
[3, '3'],
|
||||||
[
|
[2, '2'],
|
||||||
-6,
|
[-3, '-2.01'],
|
||||||
-5.4000000000000004,
|
[-2, '-2'],
|
||||||
],
|
[-1, '-1'],
|
||||||
[
|
['#VALUE!', '"ABC"'],
|
||||||
-4,
|
['#VALUE!', '""'],
|
||||||
-3.2000000000000002,
|
[1, 'true'],
|
||||||
],
|
[0, 'false'],
|
||||||
[
|
[0, '0'],
|
||||||
1,
|
[-4, '"-3.5"'],
|
||||||
1.5,
|
[8, '8.9'],
|
||||||
],
|
[-9, '-8.9'],
|
||||||
[
|
[1, 'A2'],
|
||||||
0,
|
[2, 'A3'],
|
||||||
0.10000000000000001,
|
[-4, 'A4'],
|
||||||
],
|
[-6, 'A5'],
|
||||||
[
|
[0, 'B1'],
|
||||||
-1,
|
|
||||||
-0.10000000000000001,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-3,
|
|
||||||
-2.0099999999999998,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-2,
|
|
||||||
-2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
'ABC',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1,
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-4,
|
|
||||||
'-3.5',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
8,
|
|
||||||
8.9000000000000004,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-9,
|
|
||||||
-8.9000000000000004,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,27 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[9, '10,3'],
|
||||||
9,
|
[-9, '-10,-3'],
|
||||||
10,
|
[1.4, '1.3,0.2'],
|
||||||
3,
|
[0, '5,0'],
|
||||||
],
|
[3.142, '3.14159, 0.002'],
|
||||||
[
|
[-3.140, '-3.14159,-0.02'],
|
||||||
-9,
|
[31420, '"31415.92654", 10'],
|
||||||
-10,
|
[31416, '31415.92654,"1"'],
|
||||||
-3,
|
[0, '0,5'],
|
||||||
],
|
['#NUM!', '5,-2'],
|
||||||
[
|
['#VALUE!', '"ABC",1'],
|
||||||
1.3999999999999999,
|
['#VALUE!', '1.234, "ABC"'],
|
||||||
1.3,
|
[0, ', 2'],
|
||||||
0.20000000000000001,
|
['#VALUE!', 'false, 2'],
|
||||||
],
|
['#VALUE!', 'true, 2'],
|
||||||
[
|
['#VALUE!', '"", 2'],
|
||||||
0,
|
['exception', ''],
|
||||||
5,
|
['exception', '5'],
|
||||||
0,
|
[1, 'A2, 1'],
|
||||||
],
|
[3, 'A3, 1'],
|
||||||
[
|
[-4, 'A4, -1'],
|
||||||
3.1419999999999999,
|
[-5, 'A5, -1'],
|
||||||
3.1415899999999999,
|
[0, 'B1, 1'],
|
||||||
0.002,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-3.1400000000000001,
|
|
||||||
-3.1415899999999999,
|
|
||||||
-0.02,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
31420,
|
|
||||||
31415.92654,
|
|
||||||
10,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
31416,
|
|
||||||
31415.92654,
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
5,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#NUM!',
|
|
||||||
5,
|
|
||||||
-2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
'ABC',
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
1.234,
|
|
||||||
'ABC',
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,34 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
['#VALUE!'], // exception - not enough args
|
[0, '0,2'],
|
||||||
['#VALUE!', '"ABC"', 1],
|
[663, '662.79, 0'],
|
||||||
['#VALUE!', 35.51, '"test"'],
|
[662.8, '662.79, 1'],
|
||||||
['#VALUE!', 35.51], // exception - not enough args
|
[50, '54.1, -1'],
|
||||||
[35.5, '"35.51"', '"1"'],
|
[60, '55.1, -1'],
|
||||||
[35.5, 35.51, 1],
|
[-23.7, '-23.67 ,1'],
|
||||||
[40, 35.51, -1],
|
[3, '3.2, 0'],
|
||||||
|
[3, '3.2, 0.01'],
|
||||||
|
[77, '76.9, 0'],
|
||||||
|
[3.142, '3.14159, 3'],
|
||||||
|
[-3.1, '-3.14159, 1'],
|
||||||
|
[31400, '31415.92654, "-2"'],
|
||||||
|
[31420, '31415.92654, -1'],
|
||||||
|
[4.44, '4.4400, 2'],
|
||||||
|
[5.20, '2.26 + 2.941, 2'],
|
||||||
|
[-4.44, '-4.4400, 2'],
|
||||||
|
[-5.20, '-2.26 - 2.94, 2'],
|
||||||
|
['#VALUE!', '"ABC", 1'],
|
||||||
|
['#VALUE!', '1.234, "ABC"'],
|
||||||
|
[0, ', 0'],
|
||||||
|
[0, 'false, 0'],
|
||||||
|
[1, 'true, 0'],
|
||||||
|
['#VALUE!', '"", 0'],
|
||||||
|
[1, 'A2, 0'],
|
||||||
|
[3, 'A3, 0'],
|
||||||
|
[-4, 'A4, 0'],
|
||||||
|
[-5, 'A5, 0'],
|
||||||
|
[0, 'B1, 0'],
|
||||||
|
['exception', ''],
|
||||||
|
['exception', '35.51'],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,99 +1,34 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[0, '0,2'],
|
||||||
0,
|
[662, '662.79,0'],
|
||||||
0,
|
[662.7, '662.79, 1'],
|
||||||
2,
|
[50, '54.1, -1'],
|
||||||
],
|
[50, '55.1, -1'],
|
||||||
[
|
[-23.6, '-23.67, 1'],
|
||||||
662,
|
[3, '3.2, 0'],
|
||||||
662.78999999999996,
|
[3, '3.2, 0.01'],
|
||||||
0,
|
[76, '76.9, 0'],
|
||||||
],
|
[3.141, '3.14159, 3'],
|
||||||
[
|
[-3.1, '-3.14159,1'],
|
||||||
662.70000000000005,
|
[31400, '31415.92654,"-2"'],
|
||||||
662.78999999999996,
|
[31410, '31415.92654,-1'],
|
||||||
1,
|
[4.44, '4.4400,2'],
|
||||||
],
|
[5.20, '2.26 + 2.94, 2'],
|
||||||
[
|
[-4.44, '-4.4400,2'],
|
||||||
50,
|
[-5.20, '-2.26 - 2.94, 2'],
|
||||||
54.100000000000001,
|
['#VALUE!', '"ABC",1'],
|
||||||
-1,
|
['#VALUE!', '1.234,"ABC"'],
|
||||||
],
|
[0, ', 0'],
|
||||||
[
|
[0, 'false, 0'],
|
||||||
50,
|
[1, 'true, 0'],
|
||||||
55.100000000000001,
|
['#VALUE!', '"", 0'],
|
||||||
-1,
|
[1, 'A2, 0'],
|
||||||
],
|
[2, 'A3, 0'],
|
||||||
[
|
[-3, 'A4, 0'],
|
||||||
-23.600000000000001,
|
[-5, 'A5, 0'],
|
||||||
-23.670000000000002,
|
[0, 'B1, 0'],
|
||||||
1,
|
['exception', ''],
|
||||||
],
|
['exception', '35.51'],
|
||||||
[
|
|
||||||
3,
|
|
||||||
3.2000000000000002,
|
|
||||||
0,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
3,
|
|
||||||
3.2000000000000002,
|
|
||||||
0.01,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
76,
|
|
||||||
76.900000000000006,
|
|
||||||
0,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
3.141,
|
|
||||||
3.1415899999999999,
|
|
||||||
3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-3.1000000000000001,
|
|
||||||
-3.1415899999999999,
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
31400,
|
|
||||||
31415.92654,
|
|
||||||
-2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
31410,
|
|
||||||
31415.92654,
|
|
||||||
-1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
4.44,
|
|
||||||
4.4400,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
5.20,
|
|
||||||
2.26 + 2.94,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-4.44,
|
|
||||||
-4.4400,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-5.20,
|
|
||||||
-2.26 - 2.94,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
'ABC',
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
1.234,
|
|
||||||
'ABC',
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,99 +1,34 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[0, '0,2'],
|
||||||
0,
|
[663, '662.79, 0'],
|
||||||
0,
|
[662.8, '662.79,1'],
|
||||||
2,
|
[60, '54.1,-1'],
|
||||||
],
|
[60, '55.1,-1'],
|
||||||
[
|
[-23.7, '-23.67,1'],
|
||||||
663,
|
[4, '3.2,0'],
|
||||||
662.78999999999996,
|
[4, '3.2,0.01'],
|
||||||
0,
|
[77, '76.9,0'],
|
||||||
],
|
[3.142, '3.14159,3'],
|
||||||
[
|
[-3.2, '-3.14159,1'],
|
||||||
662.79999999999995,
|
[31500, '31415.92654,"-2"'],
|
||||||
662.78999999999996,
|
[31420, '31415.92654,-1'],
|
||||||
1,
|
[4.44, '4.4400,2'],
|
||||||
],
|
[5.20, '2.26 + 2.94, 2'],
|
||||||
[
|
[-4.44, '-4.4400,2'],
|
||||||
60,
|
[-5.20, '-2.26 - 2.94, 2'],
|
||||||
54.100000000000001,
|
['#VALUE!', '"ABC",1'],
|
||||||
-1,
|
['#VALUE!', '1.234,"ABC"'],
|
||||||
],
|
[0, ', 0'],
|
||||||
[
|
[0, 'false, 0'],
|
||||||
60,
|
[1, 'true, 0'],
|
||||||
55.100000000000001,
|
['#VALUE!', '"", 0'],
|
||||||
-1,
|
[2, 'A2, 0'],
|
||||||
],
|
[3, 'A3, 0'],
|
||||||
[
|
[-4, 'A4, 0'],
|
||||||
-23.699999999999999,
|
[-6, 'A5, 0'],
|
||||||
-23.620000000000001,
|
[0, 'B1, 0'],
|
||||||
1,
|
['exception', ''],
|
||||||
],
|
['exception', '35.51'],
|
||||||
[
|
|
||||||
4,
|
|
||||||
3.2000000000000002,
|
|
||||||
0,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
4,
|
|
||||||
3.2000000000000002,
|
|
||||||
0.01,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
77,
|
|
||||||
76.900000000000006,
|
|
||||||
0,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
3.1419999999999999,
|
|
||||||
3.1415899999999999,
|
|
||||||
3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-3.2000000000000002,
|
|
||||||
-3.1415899999999999,
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
31500,
|
|
||||||
31415.92654,
|
|
||||||
-2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
31420,
|
|
||||||
31415.92654,
|
|
||||||
-1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
4.44,
|
|
||||||
4.4400,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-4.44,
|
|
||||||
-4.4400,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
5.20,
|
|
||||||
2.26 + 2.94,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-5.20,
|
|
||||||
-2.26 - 2.94,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
'ABC',
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
1.234,
|
|
||||||
'ABC',
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,99 +1,33 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[3.14, '3.14159, 2'],
|
||||||
3.1400000000000001,
|
[3.141, '3.14159, 3'],
|
||||||
3.1415899999999999,
|
[-3.14, '-3.14159, 2'],
|
||||||
2,
|
[-3.141, '-3.14159, 3'],
|
||||||
],
|
[31415.92654, '31415.92654, 10'],
|
||||||
[
|
[-31415.92654, '-31415.92654, 10'],
|
||||||
3.141,
|
[31415.92, '31415.92654, 2'],
|
||||||
3.1415899999999999,
|
[31400, '31415.92654, -2'],
|
||||||
3,
|
[0, '31415.92654, -10'],
|
||||||
],
|
[0, '-31415.92654, -10'],
|
||||||
[
|
[12000, '12345.6789, -3'],
|
||||||
-3.1400000000000001,
|
[12300, '12345.6789, -2'],
|
||||||
-3.1415899999999999,
|
[12340, '12345.6789, -1'],
|
||||||
2,
|
[12345, '12345.6789, 0'],
|
||||||
],
|
[12345.6, '12345.6789, 1'],
|
||||||
[
|
[12345.67, '12345.6789, 2'],
|
||||||
-3.141,
|
[12345.678, '12345.6789, 3'],
|
||||||
-3.1415899999999999,
|
['#VALUE!', '"ABC", 2'],
|
||||||
3,
|
['#VALUE!', '31415.92654, "ABC"'],
|
||||||
],
|
['#VALUE!', '""'],
|
||||||
[
|
[1, 'true'],
|
||||||
31415.92654,
|
[0, 'false'],
|
||||||
31415.92654,
|
[0, '0'],
|
||||||
10,
|
['exception', ''],
|
||||||
],
|
[1, 'A2'],
|
||||||
[
|
[2, 'A3'],
|
||||||
-31415.92654,
|
[-3, 'A4'],
|
||||||
-31415.92654,
|
[-5, 'A5'],
|
||||||
10,
|
[0, 'B1'],
|
||||||
],
|
|
||||||
[
|
|
||||||
31415.919999999998,
|
|
||||||
31415.92654,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
31400,
|
|
||||||
31415.92654,
|
|
||||||
-2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
0,
|
|
||||||
31415.92654,
|
|
||||||
-10,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
0,
|
|
||||||
-31415.92654,
|
|
||||||
-10,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
12000,
|
|
||||||
12345.678900000001,
|
|
||||||
-3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
12300,
|
|
||||||
12345.678900000001,
|
|
||||||
-2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
12340,
|
|
||||||
12345.678900000001,
|
|
||||||
-1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
12345,
|
|
||||||
12345.678900000001,
|
|
||||||
0,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
12345.6,
|
|
||||||
12345.678900000001,
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
12345.67,
|
|
||||||
12345.678900000001,
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
12345.678,
|
|
||||||
12345.678900000001,
|
|
||||||
3,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
'ABC',
|
|
||||||
2,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'#VALUE!',
|
|
||||||
31415.92654,
|
|
||||||
'ABC',
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue