init
This commit is contained in:
commit
72a26edcff
22092 changed files with 2101903 additions and 0 deletions
37
lib/PhpSpreadsheet/Calculation/MathTrig/Absolute.php
Normal file
37
lib/PhpSpreadsheet/Calculation/MathTrig/Absolute.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Absolute
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* ABS.
|
||||
*
|
||||
* Returns the result of builtin function abs after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|int|string rounded number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function evaluate(mixed $number): array|string|int|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return abs($number);
|
||||
}
|
||||
}
|
||||
63
lib/PhpSpreadsheet/Calculation/MathTrig/Angle.php
Normal file
63
lib/PhpSpreadsheet/Calculation/MathTrig/Angle.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Angle
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* DEGREES.
|
||||
*
|
||||
* Returns the result of builtin function rad2deg after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Rounded number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function toDegrees(mixed $number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return rad2deg($number);
|
||||
}
|
||||
|
||||
/**
|
||||
* RADIANS.
|
||||
*
|
||||
* Returns the result of builtin function deg2rad after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Rounded number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function toRadians(mixed $number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return deg2rad($number);
|
||||
}
|
||||
}
|
||||
92
lib/PhpSpreadsheet/Calculation/MathTrig/Arabic.php
Normal file
92
lib/PhpSpreadsheet/Calculation/MathTrig/Arabic.php
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Arabic
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
private const ROMAN_LOOKUP = [
|
||||
'M' => 1000,
|
||||
'D' => 500,
|
||||
'C' => 100,
|
||||
'L' => 50,
|
||||
'X' => 10,
|
||||
'V' => 5,
|
||||
'I' => 1,
|
||||
];
|
||||
|
||||
/**
|
||||
* Recursively calculate the arabic value of a roman numeral.
|
||||
*/
|
||||
private static function calculateArabic(array $roman, int &$sum = 0, int $subtract = 0): int
|
||||
{
|
||||
$numeral = array_shift($roman);
|
||||
if (!isset(self::ROMAN_LOOKUP[$numeral])) {
|
||||
throw new Exception('Invalid character detected');
|
||||
}
|
||||
|
||||
$arabic = self::ROMAN_LOOKUP[$numeral];
|
||||
if (count($roman) > 0 && isset(self::ROMAN_LOOKUP[$roman[0]]) && $arabic < self::ROMAN_LOOKUP[$roman[0]]) {
|
||||
$subtract += $arabic;
|
||||
} else {
|
||||
$sum += ($arabic - $subtract);
|
||||
$subtract = 0;
|
||||
}
|
||||
|
||||
if (count($roman) > 0) {
|
||||
self::calculateArabic($roman, $sum, $subtract);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* ARABIC.
|
||||
*
|
||||
* Converts a Roman numeral to an Arabic numeral.
|
||||
*
|
||||
* Excel Function:
|
||||
* ARABIC(text)
|
||||
*
|
||||
* @param mixed $roman Should be a string, or can be an array of strings
|
||||
*
|
||||
* @return array|int|string the arabic numberal contrived from the roman numeral
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function evaluate(mixed $roman): array|int|string
|
||||
{
|
||||
if (is_array($roman)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $roman);
|
||||
}
|
||||
|
||||
// An empty string should return 0
|
||||
$roman = substr(trim(strtoupper((string) $roman)), 0, 255);
|
||||
if ($roman === '') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert the roman numeral to an arabic number
|
||||
$negativeNumber = $roman[0] === '-';
|
||||
if ($negativeNumber) {
|
||||
$roman = substr($roman, 1);
|
||||
}
|
||||
|
||||
try {
|
||||
$arabic = self::calculateArabic(str_split($roman));
|
||||
} catch (Exception) {
|
||||
return ExcelError::VALUE(); // Invalid character detected
|
||||
}
|
||||
|
||||
if ($negativeNumber) {
|
||||
$arabic *= -1; // The number should be negative
|
||||
}
|
||||
|
||||
return $arabic;
|
||||
}
|
||||
}
|
||||
65
lib/PhpSpreadsheet/Calculation/MathTrig/Base.php
Normal file
65
lib/PhpSpreadsheet/Calculation/MathTrig/Base.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Base
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* BASE.
|
||||
*
|
||||
* Converts a number into a text representation with the given radix (base).
|
||||
*
|
||||
* Excel Function:
|
||||
* BASE(Number, Radix [Min_length])
|
||||
*
|
||||
* @param mixed $number expect float
|
||||
* Or can be an array of values
|
||||
* @param mixed $radix expect float
|
||||
* Or can be an array of values
|
||||
* @param mixed $minLength expect int or null
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|string the text representation with the given radix (base)
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function evaluate(mixed $number, mixed $radix, mixed $minLength = null): array|string
|
||||
{
|
||||
if (is_array($number) || is_array($radix) || is_array($minLength)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $radix, $minLength);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = (float) floor(Helpers::validateNumericNullBool($number));
|
||||
$radix = (int) Helpers::validateNumericNullBool($radix);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return self::calculate($number, $radix, $minLength);
|
||||
}
|
||||
|
||||
private static function calculate(float $number, int $radix, mixed $minLength): string
|
||||
{
|
||||
if ($minLength === null || is_numeric($minLength)) {
|
||||
if ($number < 0 || $number >= 2 ** 53 || $radix < 2 || $radix > 36) {
|
||||
return ExcelError::NAN(); // Numeric range constraints
|
||||
}
|
||||
|
||||
$outcome = strtoupper((string) base_convert("$number", 10, $radix));
|
||||
if ($minLength !== null) {
|
||||
$outcome = str_pad($outcome, (int) $minLength, '0', STR_PAD_LEFT); // String padding
|
||||
}
|
||||
|
||||
return $outcome;
|
||||
}
|
||||
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
}
|
||||
165
lib/PhpSpreadsheet/Calculation/MathTrig/Ceiling.php
Normal file
165
lib/PhpSpreadsheet/Calculation/MathTrig/Ceiling.php
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Ceiling
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* 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 array|float $number the number you want the ceiling
|
||||
* Or can be an array of values
|
||||
* @param array|float $significance the multiple to which you want to round
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function ceiling($number, $significance = null)
|
||||
{
|
||||
if (is_array($number) || is_array($significance)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance);
|
||||
}
|
||||
|
||||
if ($significance === null) {
|
||||
self::floorCheck1Arg();
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return self::argumentsOk((float) $number, (float) $significance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Or can be an array of values
|
||||
* @param mixed $significance Significance
|
||||
* Or can be an array of values
|
||||
* @param array|int $mode direction to round negative numbers
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function math(mixed $number, mixed $significance = null, $mode = 0): array|string|float
|
||||
{
|
||||
if (is_array($number) || is_array($significance) || is_array($mode)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance, $mode);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
|
||||
$mode = Helpers::validateNumericNullSubstitution($mode, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Or can be an array of values
|
||||
* @param array|float $significance the multiple to which you want to round
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function precise(mixed $number, $significance = 1): array|string|float
|
||||
{
|
||||
if (is_array($number) || is_array($significance)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$significance = Helpers::validateNumericNullSubstitution($significance, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if (!$significance) {
|
||||
return 0.0;
|
||||
}
|
||||
$result = $number / abs($significance);
|
||||
|
||||
return ceil($result) * $significance * (($significance < 0) ? -1 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Let CEILINGMATH complexity pass Scrutinizer.
|
||||
*/
|
||||
private static function ceilingMathTest(float $significance, float $number, int $mode): bool
|
||||
{
|
||||
return ($significance < 0) || ($number < 0 && !empty($mode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoid Scrutinizer problems concerning complexity.
|
||||
*/
|
||||
private static function argumentsOk(float $number, float $significance): float|string
|
||||
{
|
||||
if (empty($number * $significance)) {
|
||||
return 0.0;
|
||||
}
|
||||
if (Helpers::returnSign($number) == Helpers::returnSign($significance)) {
|
||||
return ceil($number / $significance) * $significance;
|
||||
}
|
||||
|
||||
return ExcelError::NAN();
|
||||
}
|
||||
|
||||
private static function floorCheck1Arg(): void
|
||||
{
|
||||
$compatibility = Functions::getCompatibilityMode();
|
||||
if ($compatibility === Functions::COMPATIBILITY_EXCEL) {
|
||||
throw new Exception('Excel requires 2 arguments for CEILING');
|
||||
}
|
||||
}
|
||||
}
|
||||
91
lib/PhpSpreadsheet/Calculation/MathTrig/Combinations.php
Normal file
91
lib/PhpSpreadsheet/Calculation/MathTrig/Combinations.php
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Combinations
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* COMBIN.
|
||||
*
|
||||
* Returns the number of combinations for a given number of items. Use COMBIN to
|
||||
* determine the total possible number of groups for a given number of items.
|
||||
*
|
||||
* Excel Function:
|
||||
* COMBIN(numObjs,numInSet)
|
||||
*
|
||||
* @param mixed $numObjs Number of different objects, or can be an array of numbers
|
||||
* @param mixed $numInSet Number of objects in each combination, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Number of combinations, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function withoutRepetition(mixed $numObjs, mixed $numInSet): array|string|float
|
||||
{
|
||||
if (is_array($numObjs) || is_array($numInSet)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $numObjs, $numInSet);
|
||||
}
|
||||
|
||||
try {
|
||||
$numObjs = Helpers::validateNumericNullSubstitution($numObjs, null);
|
||||
$numInSet = Helpers::validateNumericNullSubstitution($numInSet, null);
|
||||
Helpers::validateNotNegative($numInSet);
|
||||
Helpers::validateNotNegative($numObjs - $numInSet);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return round(Factorial::fact($numObjs) / Factorial::fact($numObjs - $numInSet)) / Factorial::fact($numInSet); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* COMBINA.
|
||||
*
|
||||
* Returns the number of combinations for a given number of items. Use COMBIN to
|
||||
* determine the total possible number of groups for a given number of items.
|
||||
*
|
||||
* Excel Function:
|
||||
* COMBINA(numObjs,numInSet)
|
||||
*
|
||||
* @param mixed $numObjs Number of different objects, or can be an array of numbers
|
||||
* @param mixed $numInSet Number of objects in each combination, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|int|string Number of combinations, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function withRepetition(mixed $numObjs, mixed $numInSet): array|int|string|float
|
||||
{
|
||||
if (is_array($numObjs) || is_array($numInSet)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $numObjs, $numInSet);
|
||||
}
|
||||
|
||||
try {
|
||||
$numObjs = Helpers::validateNumericNullSubstitution($numObjs, null);
|
||||
$numInSet = Helpers::validateNumericNullSubstitution($numInSet, null);
|
||||
Helpers::validateNotNegative($numInSet);
|
||||
Helpers::validateNotNegative($numObjs);
|
||||
$numObjs = (int) $numObjs;
|
||||
$numInSet = (int) $numInSet;
|
||||
// Microsoft documentation says following is true, but Excel
|
||||
// does not enforce this restriction.
|
||||
//Helpers::validateNotNegative($numObjs - $numInSet);
|
||||
if ($numObjs === 0) {
|
||||
Helpers::validateNotNegative(-$numInSet);
|
||||
|
||||
return 1;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return round(
|
||||
Factorial::fact($numObjs + $numInSet - 1) / Factorial::fact($numObjs - 1) // @phpstan-ignore-line
|
||||
) / Factorial::fact($numInSet);
|
||||
}
|
||||
}
|
||||
37
lib/PhpSpreadsheet/Calculation/MathTrig/Exp.php
Normal file
37
lib/PhpSpreadsheet/Calculation/MathTrig/Exp.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Exp
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* EXP.
|
||||
*
|
||||
* Returns the result of builtin function exp after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Rounded number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function evaluate(mixed $number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return exp($number);
|
||||
}
|
||||
}
|
||||
126
lib/PhpSpreadsheet/Calculation/MathTrig/Factorial.php
Normal file
126
lib/PhpSpreadsheet/Calculation/MathTrig/Factorial.php
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
class Factorial
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* FACT.
|
||||
*
|
||||
* Returns the factorial of a number.
|
||||
* The factorial of a number is equal to 1*2*3*...* number.
|
||||
*
|
||||
* Excel Function:
|
||||
* FACT(factVal)
|
||||
*
|
||||
* @param array|float $factVal Factorial Value, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|int|string Factorial, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function fact($factVal): array|string|float|int
|
||||
{
|
||||
if (is_array($factVal)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $factVal);
|
||||
}
|
||||
|
||||
try {
|
||||
$factVal = Helpers::validateNumericNullBool($factVal);
|
||||
Helpers::validateNotNegative($factVal);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$factLoop = floor($factVal);
|
||||
if ($factVal > $factLoop) {
|
||||
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) {
|
||||
return Statistical\Distributions\Gamma::gammaValue($factVal + 1);
|
||||
}
|
||||
}
|
||||
|
||||
$factorial = 1;
|
||||
while ($factLoop > 1) {
|
||||
$factorial *= $factLoop--;
|
||||
}
|
||||
|
||||
return $factorial;
|
||||
}
|
||||
|
||||
/**
|
||||
* FACTDOUBLE.
|
||||
*
|
||||
* Returns the double factorial of a number.
|
||||
*
|
||||
* Excel Function:
|
||||
* FACTDOUBLE(factVal)
|
||||
*
|
||||
* @param array|float $factVal Factorial Value, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|int|string Double Factorial, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function factDouble($factVal): array|string|float|int
|
||||
{
|
||||
if (is_array($factVal)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $factVal);
|
||||
}
|
||||
|
||||
try {
|
||||
$factVal = Helpers::validateNumericNullSubstitution($factVal, 0);
|
||||
Helpers::validateNotNegative($factVal);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$factLoop = floor($factVal);
|
||||
$factorial = 1;
|
||||
while ($factLoop > 1) {
|
||||
$factorial *= $factLoop;
|
||||
$factLoop -= 2;
|
||||
}
|
||||
|
||||
return $factorial;
|
||||
}
|
||||
|
||||
/**
|
||||
* MULTINOMIAL.
|
||||
*
|
||||
* Returns the ratio of the factorial of a sum of values to the product of factorials.
|
||||
*
|
||||
* @param mixed[] $args An array of mixed values for the Data Series
|
||||
*
|
||||
* @return float|int|string The result, or a string containing an error
|
||||
*/
|
||||
public static function multinomial(...$args): string|int|float
|
||||
{
|
||||
$summer = 0;
|
||||
$divisor = 1;
|
||||
|
||||
try {
|
||||
// Loop through arguments
|
||||
foreach (Functions::flattenArray($args) as $argx) {
|
||||
$arg = Helpers::validateNumericNullSubstitution($argx, null);
|
||||
Helpers::validateNotNegative($arg);
|
||||
$arg = (int) $arg;
|
||||
$summer += $arg;
|
||||
$divisor *= self::fact($arg);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$summer = self::fact($summer);
|
||||
|
||||
return is_numeric($summer) ? ($summer / $divisor) : ExcelError::VALUE();
|
||||
}
|
||||
}
|
||||
191
lib/PhpSpreadsheet/Calculation/MathTrig/Floor.php
Normal file
191
lib/PhpSpreadsheet/Calculation/MathTrig/Floor.php
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Floor
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
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 mixed $number Expect float. Number to round
|
||||
* Or can be an array of values
|
||||
* @param mixed $significance Expect float. Significance
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function floor(mixed $number, mixed $significance = null)
|
||||
{
|
||||
if (is_array($number) || is_array($significance)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance);
|
||||
}
|
||||
|
||||
if ($significance === null) {
|
||||
self::floorCheck1Arg();
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return self::argumentsOk((float) $number, (float) $significance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Or can be an array of values
|
||||
* @param mixed $significance Significance
|
||||
* Or can be an array of values
|
||||
* @param mixed $mode direction to round negative numbers
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function math(mixed $number, mixed $significance = null, mixed $mode = 0)
|
||||
{
|
||||
if (is_array($number) || is_array($significance) || is_array($mode)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance, $mode);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
|
||||
$mode = Helpers::validateNumericNullSubstitution($mode, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return self::argsOk((float) $number, (float) $significance, (int) $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* FLOOR.PRECISE.
|
||||
*
|
||||
* Rounds number down, toward zero, to the nearest multiple of significance.
|
||||
*
|
||||
* Excel Function:
|
||||
* FLOOR.PRECISE(number[,significance])
|
||||
*
|
||||
* @param array|float $number Number to round
|
||||
* Or can be an array of values
|
||||
* @param array|float $significance Significance
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function precise($number, $significance = 1)
|
||||
{
|
||||
if (is_array($number) || is_array($significance)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$significance = Helpers::validateNumericNullSubstitution($significance, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return self::argumentsOkPrecise((float) $number, (float) $significance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoid Scrutinizer problems concerning complexity.
|
||||
*/
|
||||
private static function argumentsOkPrecise(float $number, float $significance): string|float
|
||||
{
|
||||
if ($significance == 0.0) {
|
||||
return ExcelError::DIV0();
|
||||
}
|
||||
if ($number == 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return floor($number / abs($significance)) * abs($significance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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): string|float
|
||||
{
|
||||
if (!$significance) {
|
||||
return ExcelError::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 Helpers::returnSign($significance) == -1 || (Helpers::returnSign($number) == -1 && !empty($mode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoid Scrutinizer problems concerning complexity.
|
||||
*/
|
||||
private static function argumentsOk(float $number, float $significance): string|float
|
||||
{
|
||||
if ($significance == 0.0) {
|
||||
return ExcelError::DIV0();
|
||||
}
|
||||
if ($number == 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (Helpers::returnSign($significance) == 1) {
|
||||
return floor($number / $significance) * $significance;
|
||||
}
|
||||
if (Helpers::returnSign($number) == -1 && Helpers::returnSign($significance) == -1) {
|
||||
return floor($number / $significance) * $significance;
|
||||
}
|
||||
|
||||
return ExcelError::NAN();
|
||||
}
|
||||
}
|
||||
65
lib/PhpSpreadsheet/Calculation/MathTrig/Gcd.php
Normal file
65
lib/PhpSpreadsheet/Calculation/MathTrig/Gcd.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Gcd
|
||||
{
|
||||
/**
|
||||
* Recursively determine GCD.
|
||||
*
|
||||
* Returns the greatest common divisor of a series of numbers.
|
||||
* The greatest common divisor is the largest integer that divides both
|
||||
* number1 and number2 without a remainder.
|
||||
*
|
||||
* Excel Function:
|
||||
* GCD(number1[,number2[, ...]])
|
||||
*/
|
||||
private static function evaluateGCD(float|int $a, float|int $b): float|int
|
||||
{
|
||||
return $b ? self::evaluateGCD($b, $a % $b) : $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* GCD.
|
||||
*
|
||||
* Returns the greatest common divisor of a series of numbers.
|
||||
* The greatest common divisor is the largest integer that divides both
|
||||
* number1 and number2 without a remainder.
|
||||
*
|
||||
* Excel Function:
|
||||
* GCD(number1[,number2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|int|string Greatest Common Divisor, or a string containing an error
|
||||
*/
|
||||
public static function evaluate(mixed ...$args)
|
||||
{
|
||||
try {
|
||||
$arrayArgs = [];
|
||||
foreach (Functions::flattenArray($args) as $value1) {
|
||||
if ($value1 !== null) {
|
||||
$value = Helpers::validateNumericNullSubstitution($value1, 1);
|
||||
Helpers::validateNotNegative($value);
|
||||
$arrayArgs[] = (int) $value;
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if (count($arrayArgs) <= 0) {
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
$gcd = (int) array_pop($arrayArgs);
|
||||
do {
|
||||
$gcd = self::evaluateGCD($gcd, (int) array_pop($arrayArgs));
|
||||
} while (!empty($arrayArgs));
|
||||
|
||||
return $gcd;
|
||||
}
|
||||
}
|
||||
111
lib/PhpSpreadsheet/Calculation/MathTrig/Helpers.php
Normal file
111
lib/PhpSpreadsheet/Calculation/MathTrig/Helpers.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Helpers
|
||||
{
|
||||
/**
|
||||
* Many functions accept null/false/true argument treated as 0/0/1.
|
||||
*
|
||||
* @return float|string quotient or DIV0 if denominator is too small
|
||||
*/
|
||||
public static function verySmallDenominator(float $numerator, float $denominator): string|float
|
||||
{
|
||||
return (abs($denominator) < 1.0E-12) ? ExcelError::DIV0() : ($numerator / $denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Many functions accept null/false/true argument treated as 0/0/1.
|
||||
*/
|
||||
public static function validateNumericNullBool(mixed $number): int|float
|
||||
{
|
||||
$number = Functions::flattenSingleValue($number);
|
||||
if ($number === null) {
|
||||
return 0;
|
||||
}
|
||||
if (is_bool($number)) {
|
||||
return (int) $number;
|
||||
}
|
||||
if (is_numeric($number)) {
|
||||
return 0 + $number;
|
||||
}
|
||||
|
||||
throw new Exception(ExcelError::throwError($number));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate numeric, but allow substitute for null.
|
||||
*/
|
||||
public static function validateNumericNullSubstitution(mixed $number, null|float|int $substitute): float|int
|
||||
{
|
||||
$number = Functions::flattenSingleValue($number);
|
||||
if ($number === null && $substitute !== null) {
|
||||
return $substitute;
|
||||
}
|
||||
if (is_numeric($number)) {
|
||||
return 0 + $number;
|
||||
}
|
||||
|
||||
throw new Exception(ExcelError::throwError($number));
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm number >= 0.
|
||||
*/
|
||||
public static function validateNotNegative(float|int $number, ?string $except = null): void
|
||||
{
|
||||
if ($number >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception($except ?? ExcelError::NAN());
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm number > 0.
|
||||
*/
|
||||
public static function validatePositive(float|int $number, ?string $except = null): void
|
||||
{
|
||||
if ($number > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception($except ?? ExcelError::NAN());
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm number != 0.
|
||||
*/
|
||||
public static function validateNotZero(float|int $number): void
|
||||
{
|
||||
if ($number) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception(ExcelError::DIV0());
|
||||
}
|
||||
|
||||
public static function returnSign(float $number): int
|
||||
{
|
||||
return $number ? (($number > 0) ? 1 : -1) : 0;
|
||||
}
|
||||
|
||||
public static function getEven(float $number): float
|
||||
{
|
||||
$significance = 2 * self::returnSign($number);
|
||||
|
||||
return $significance ? (ceil($number / $significance) * $significance) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return NAN or value depending on argument.
|
||||
*/
|
||||
public static function numberOrNan(float $result): float|string
|
||||
{
|
||||
return is_nan($result) ? ExcelError::NAN() : $result;
|
||||
}
|
||||
}
|
||||
40
lib/PhpSpreadsheet/Calculation/MathTrig/IntClass.php
Normal file
40
lib/PhpSpreadsheet/Calculation/MathTrig/IntClass.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class IntClass
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* INT.
|
||||
*
|
||||
* Casts a floating point value to an integer
|
||||
*
|
||||
* Excel Function:
|
||||
* INT(number)
|
||||
*
|
||||
* @param array|float $number Number to cast to an integer, or can be an array of numbers
|
||||
*
|
||||
* @return array|int|string Integer value, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function evaluate($number): array|string|int
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return (int) floor($number);
|
||||
}
|
||||
}
|
||||
111
lib/PhpSpreadsheet/Calculation/MathTrig/Lcm.php
Normal file
111
lib/PhpSpreadsheet/Calculation/MathTrig/Lcm.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Lcm
|
||||
{
|
||||
//
|
||||
// Private method to return an array of the factors of the input value
|
||||
//
|
||||
private static function factors(float $value): array
|
||||
{
|
||||
$startVal = floor(sqrt($value));
|
||||
|
||||
$factorArray = [];
|
||||
for ($i = $startVal; $i > 1; --$i) {
|
||||
if (($value % $i) == 0) {
|
||||
$factorArray = array_merge($factorArray, self::factors($value / $i));
|
||||
$factorArray = array_merge($factorArray, self::factors($i));
|
||||
if ($i <= sqrt($value)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($factorArray)) {
|
||||
rsort($factorArray);
|
||||
|
||||
return $factorArray;
|
||||
}
|
||||
|
||||
return [(int) $value];
|
||||
}
|
||||
|
||||
/**
|
||||
* LCM.
|
||||
*
|
||||
* Returns the lowest common multiplier of a series of numbers
|
||||
* The least common multiple is the smallest positive integer that is a multiple
|
||||
* of all integer arguments number1, number2, and so on. Use LCM to add fractions
|
||||
* with different denominators.
|
||||
*
|
||||
* Excel Function:
|
||||
* LCM(number1[,number2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return int|string Lowest Common Multiplier, or a string containing an error
|
||||
*/
|
||||
public static function evaluate(mixed ...$args): int|string
|
||||
{
|
||||
try {
|
||||
$arrayArgs = [];
|
||||
$anyZeros = 0;
|
||||
$anyNonNulls = 0;
|
||||
foreach (Functions::flattenArray($args) as $value1) {
|
||||
$anyNonNulls += (int) ($value1 !== null);
|
||||
$value = Helpers::validateNumericNullSubstitution($value1, 1);
|
||||
Helpers::validateNotNegative($value);
|
||||
$arrayArgs[] = (int) $value;
|
||||
$anyZeros += (int) !((bool) $value);
|
||||
}
|
||||
self::testNonNulls($anyNonNulls);
|
||||
if ($anyZeros) {
|
||||
return 0;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$returnValue = 1;
|
||||
$allPoweredFactors = [];
|
||||
// Loop through arguments
|
||||
foreach ($arrayArgs as $value) {
|
||||
$myFactors = self::factors(floor($value));
|
||||
$myCountedFactors = array_count_values($myFactors);
|
||||
$myPoweredFactors = [];
|
||||
foreach ($myCountedFactors as $myCountedFactor => $myCountedPower) {
|
||||
$myPoweredFactors[$myCountedFactor] = $myCountedFactor ** $myCountedPower;
|
||||
}
|
||||
self::processPoweredFactors($allPoweredFactors, $myPoweredFactors);
|
||||
}
|
||||
foreach ($allPoweredFactors as $allPoweredFactor) {
|
||||
$returnValue *= (int) $allPoweredFactor;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
private static function processPoweredFactors(array &$allPoweredFactors, array &$myPoweredFactors): void
|
||||
{
|
||||
foreach ($myPoweredFactors as $myPoweredValue => $myPoweredFactor) {
|
||||
if (isset($allPoweredFactors[$myPoweredValue])) {
|
||||
if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) {
|
||||
$allPoweredFactors[$myPoweredValue] = $myPoweredFactor;
|
||||
}
|
||||
} else {
|
||||
$allPoweredFactors[$myPoweredValue] = $myPoweredFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function testNonNulls(int $anyNonNulls): void
|
||||
{
|
||||
if (!$anyNonNulls) {
|
||||
throw new Exception(ExcelError::VALUE());
|
||||
}
|
||||
}
|
||||
}
|
||||
102
lib/PhpSpreadsheet/Calculation/MathTrig/Logarithms.php
Normal file
102
lib/PhpSpreadsheet/Calculation/MathTrig/Logarithms.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Logarithms
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* LOG_BASE.
|
||||
*
|
||||
* Returns the logarithm of a number to a specified base. The default base is 10.
|
||||
*
|
||||
* Excel Function:
|
||||
* LOG(number[,base])
|
||||
*
|
||||
* @param mixed $number The positive real number for which you want the logarithm
|
||||
* Or can be an array of values
|
||||
* @param mixed $base The base of the logarithm. If base is omitted, it is assumed to be 10.
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string The result, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function withBase(mixed $number, mixed $base = 10): array|string|float
|
||||
{
|
||||
if (is_array($number) || is_array($base)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $base);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
Helpers::validatePositive($number);
|
||||
$base = Helpers::validateNumericNullBool($base);
|
||||
Helpers::validatePositive($base);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return log($number, $base);
|
||||
}
|
||||
|
||||
/**
|
||||
* LOG10.
|
||||
*
|
||||
* Returns the result of builtin function log after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Rounded number
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function base10(mixed $number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
Helpers::validatePositive($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return log10($number);
|
||||
}
|
||||
|
||||
/**
|
||||
* LN.
|
||||
*
|
||||
* Returns the result of builtin function log after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Rounded number
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function natural(mixed $number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
Helpers::validatePositive($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return log($number);
|
||||
}
|
||||
}
|
||||
179
lib/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php
Normal file
179
lib/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use Matrix\Builder;
|
||||
use Matrix\Div0Exception as MatrixDiv0Exception;
|
||||
use Matrix\Exception as MatrixException;
|
||||
use Matrix\Matrix;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class MatrixFunctions
|
||||
{
|
||||
/**
|
||||
* Convert parameter to Matrix.
|
||||
*
|
||||
* @param mixed $matrixValues A matrix of values
|
||||
*/
|
||||
private static function getMatrix(mixed $matrixValues): Matrix
|
||||
{
|
||||
$matrixData = [];
|
||||
if (!is_array($matrixValues)) {
|
||||
$matrixValues = [[$matrixValues]];
|
||||
}
|
||||
|
||||
$row = 0;
|
||||
foreach ($matrixValues as $matrixRow) {
|
||||
if (!is_array($matrixRow)) {
|
||||
$matrixRow = [$matrixRow];
|
||||
}
|
||||
$column = 0;
|
||||
foreach ($matrixRow as $matrixCell) {
|
||||
if ((is_string($matrixCell)) || ($matrixCell === null)) {
|
||||
throw new Exception(ExcelError::VALUE());
|
||||
}
|
||||
$matrixData[$row][$column] = $matrixCell;
|
||||
++$column;
|
||||
}
|
||||
++$row;
|
||||
}
|
||||
|
||||
return new Matrix($matrixData);
|
||||
}
|
||||
|
||||
/**
|
||||
* SEQUENCE.
|
||||
*
|
||||
* Generates a list of sequential numbers in an array.
|
||||
*
|
||||
* Excel Function:
|
||||
* SEQUENCE(rows,[columns],[start],[step])
|
||||
*
|
||||
* @param mixed $rows the number of rows to return, defaults to 1
|
||||
* @param mixed $columns the number of columns to return, defaults to 1
|
||||
* @param mixed $start the first number in the sequence, defaults to 1
|
||||
* @param mixed $step the amount to increment each subsequent value in the array, defaults to 1
|
||||
*
|
||||
* @return array|string The resulting array, or a string containing an error
|
||||
*/
|
||||
public static function sequence(mixed $rows = 1, mixed $columns = 1, mixed $start = 1, mixed $step = 1): string|array
|
||||
{
|
||||
try {
|
||||
$rows = (int) Helpers::validateNumericNullSubstitution($rows, 1);
|
||||
Helpers::validatePositive($rows);
|
||||
$columns = (int) Helpers::validateNumericNullSubstitution($columns, 1);
|
||||
Helpers::validatePositive($columns);
|
||||
$start = Helpers::validateNumericNullSubstitution($start, 1);
|
||||
$step = Helpers::validateNumericNullSubstitution($step, 1);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if ($step === 0) {
|
||||
return array_chunk(
|
||||
array_fill(0, $rows * $columns, $start),
|
||||
max($columns, 1)
|
||||
);
|
||||
}
|
||||
|
||||
return array_chunk(
|
||||
range($start, $start + (($rows * $columns - 1) * $step), $step),
|
||||
max($columns, 1)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* MDETERM.
|
||||
*
|
||||
* Returns the matrix determinant of an array.
|
||||
*
|
||||
* Excel Function:
|
||||
* MDETERM(array)
|
||||
*
|
||||
* @param mixed $matrixValues A matrix of values
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function determinant(mixed $matrixValues)
|
||||
{
|
||||
try {
|
||||
$matrix = self::getMatrix($matrixValues);
|
||||
|
||||
return $matrix->determinant();
|
||||
} catch (MatrixException) {
|
||||
return ExcelError::VALUE();
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MINVERSE.
|
||||
*
|
||||
* Returns the inverse matrix for the matrix stored in an array.
|
||||
*
|
||||
* Excel Function:
|
||||
* MINVERSE(array)
|
||||
*
|
||||
* @param mixed $matrixValues A matrix of values
|
||||
*
|
||||
* @return array|string The result, or a string containing an error
|
||||
*/
|
||||
public static function inverse(mixed $matrixValues): array|string
|
||||
{
|
||||
try {
|
||||
$matrix = self::getMatrix($matrixValues);
|
||||
|
||||
return $matrix->inverse()->toArray();
|
||||
} catch (MatrixDiv0Exception) {
|
||||
return ExcelError::NAN();
|
||||
} catch (MatrixException) {
|
||||
return ExcelError::VALUE();
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MMULT.
|
||||
*
|
||||
* @param mixed $matrixData1 A matrix of values
|
||||
* @param mixed $matrixData2 A matrix of values
|
||||
*
|
||||
* @return array|string The result, or a string containing an error
|
||||
*/
|
||||
public static function multiply(mixed $matrixData1, mixed $matrixData2): array|string
|
||||
{
|
||||
try {
|
||||
$matrixA = self::getMatrix($matrixData1);
|
||||
$matrixB = self::getMatrix($matrixData2);
|
||||
|
||||
return $matrixA->multiply($matrixB)->toArray();
|
||||
} catch (MatrixException) {
|
||||
return ExcelError::VALUE();
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MUnit.
|
||||
*
|
||||
* @param mixed $dimension Number of rows and columns
|
||||
*
|
||||
* @return array|string The result, or a string containing an error
|
||||
*/
|
||||
public static function identity(mixed $dimension)
|
||||
{
|
||||
try {
|
||||
$dimension = (int) Helpers::validateNumericNullBool($dimension);
|
||||
Helpers::validatePositive($dimension, ExcelError::VALUE());
|
||||
$matrix = Builder::createIdentityMatrix($dimension, 0)->toArray();
|
||||
|
||||
return $matrix;
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
155
lib/PhpSpreadsheet/Calculation/MathTrig/Operations.php
Normal file
155
lib/PhpSpreadsheet/Calculation/MathTrig/Operations.php
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Operations
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* MOD.
|
||||
*
|
||||
* @param mixed $dividend Dividend
|
||||
* Or can be an array of values
|
||||
* @param mixed $divisor Divisor
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Remainder, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function mod(mixed $dividend, mixed $divisor): array|string|float
|
||||
{
|
||||
if (is_array($dividend) || is_array($divisor)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $dividend, $divisor);
|
||||
}
|
||||
|
||||
try {
|
||||
$dividend = Helpers::validateNumericNullBool($dividend);
|
||||
$divisor = Helpers::validateNumericNullBool($divisor);
|
||||
Helpers::validateNotZero($divisor);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if (($dividend < 0.0) && ($divisor > 0.0)) {
|
||||
return $divisor - fmod(abs($dividend), $divisor);
|
||||
}
|
||||
if (($dividend > 0.0) && ($divisor < 0.0)) {
|
||||
return $divisor + fmod($dividend, abs($divisor));
|
||||
}
|
||||
|
||||
return fmod($dividend, $divisor);
|
||||
}
|
||||
|
||||
/**
|
||||
* POWER.
|
||||
*
|
||||
* Computes x raised to the power y.
|
||||
*
|
||||
* @param array|float|int|string $x Or can be an array of values
|
||||
* @param array|float|int|string $y Or can be an array of values
|
||||
*
|
||||
* @return array|float|int|string The result, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function power(array|float|int|string $x, array|float|int|string $y): array|float|int|string
|
||||
{
|
||||
if (is_array($x) || is_array($y)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $y);
|
||||
}
|
||||
|
||||
try {
|
||||
$x = Helpers::validateNumericNullBool($x);
|
||||
$y = Helpers::validateNumericNullBool($y);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Validate parameters
|
||||
if (!$x && !$y) {
|
||||
return ExcelError::NAN();
|
||||
}
|
||||
if (!$x && $y < 0.0) {
|
||||
return ExcelError::DIV0();
|
||||
}
|
||||
|
||||
// Return
|
||||
$result = $x ** $y;
|
||||
|
||||
return Helpers::numberOrNan($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* PRODUCT.
|
||||
*
|
||||
* PRODUCT returns the product of all the values and cells referenced in the argument list.
|
||||
*
|
||||
* Excel Function:
|
||||
* PRODUCT(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*/
|
||||
public static function product(mixed ...$args): string|float
|
||||
{
|
||||
$args = array_filter(
|
||||
Functions::flattenArray($args),
|
||||
fn ($value): bool => $value !== null
|
||||
);
|
||||
|
||||
// Return value
|
||||
$returnValue = (count($args) === 0) ? 0.0 : 1.0;
|
||||
|
||||
// Loop through arguments
|
||||
foreach ($args as $arg) {
|
||||
// Is it a numeric value?
|
||||
if (is_numeric($arg)) {
|
||||
$returnValue *= $arg;
|
||||
} else {
|
||||
return ExcelError::throwError($arg);
|
||||
}
|
||||
}
|
||||
|
||||
return (float) $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* QUOTIENT.
|
||||
*
|
||||
* QUOTIENT function returns the integer portion of a division. Numerator is the divided number
|
||||
* and denominator is the divisor.
|
||||
*
|
||||
* Excel Function:
|
||||
* QUOTIENT(value1,value2)
|
||||
*
|
||||
* @param mixed $numerator Expect float|int
|
||||
* Or can be an array of values
|
||||
* @param mixed $denominator Expect float|int
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|int|string If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function quotient(mixed $numerator, mixed $denominator): array|string|int
|
||||
{
|
||||
if (is_array($numerator) || is_array($denominator)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $numerator, $denominator);
|
||||
}
|
||||
|
||||
try {
|
||||
$numerator = Helpers::validateNumericNullSubstitution($numerator, 0);
|
||||
$denominator = Helpers::validateNumericNullSubstitution($denominator, 0);
|
||||
Helpers::validateNotZero($denominator);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return (int) ($numerator / $denominator);
|
||||
}
|
||||
}
|
||||
99
lib/PhpSpreadsheet/Calculation/MathTrig/Random.php
Normal file
99
lib/PhpSpreadsheet/Calculation/MathTrig/Random.php
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Random
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* RAND.
|
||||
*
|
||||
* @return float|int Random number
|
||||
*/
|
||||
public static function rand(): int|float
|
||||
{
|
||||
return mt_rand(0, 10000000) / 10000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* RANDBETWEEN.
|
||||
*
|
||||
* @param mixed $min Minimal value
|
||||
* Or can be an array of values
|
||||
* @param mixed $max Maximal value
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return array|int|string Random number
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function randBetween(mixed $min, mixed $max): array|string|int
|
||||
{
|
||||
if (is_array($min) || is_array($max)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $min, $max);
|
||||
}
|
||||
|
||||
try {
|
||||
$min = (int) Helpers::validateNumericNullBool($min);
|
||||
$max = (int) Helpers::validateNumericNullBool($max);
|
||||
Helpers::validateNotNegative($max - $min);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return mt_rand($min, $max);
|
||||
}
|
||||
|
||||
/**
|
||||
* RANDARRAY.
|
||||
*
|
||||
* Generates a list of sequential numbers in an array.
|
||||
*
|
||||
* Excel Function:
|
||||
* RANDARRAY([rows],[columns],[start],[step])
|
||||
*
|
||||
* @param mixed $rows the number of rows to return, defaults to 1
|
||||
* @param mixed $columns the number of columns to return, defaults to 1
|
||||
* @param mixed $min the minimum number to be returned, defaults to 0
|
||||
* @param mixed $max the maximum number to be returned, defaults to 1
|
||||
* @param bool $wholeNumber the type of numbers to return:
|
||||
* False - Decimal numbers to 15 decimal places. (default)
|
||||
* True - Whole (integer) numbers
|
||||
*
|
||||
* @return array|string The resulting array, or a string containing an error
|
||||
*/
|
||||
public static function randArray(mixed $rows = 1, mixed $columns = 1, mixed $min = 0, mixed $max = 1, bool $wholeNumber = false): string|array
|
||||
{
|
||||
try {
|
||||
$rows = (int) Helpers::validateNumericNullSubstitution($rows, 1);
|
||||
Helpers::validatePositive($rows);
|
||||
$columns = (int) Helpers::validateNumericNullSubstitution($columns, 1);
|
||||
Helpers::validatePositive($columns);
|
||||
$min = Helpers::validateNumericNullSubstitution($min, 1);
|
||||
$max = Helpers::validateNumericNullSubstitution($max, 1);
|
||||
|
||||
if ($max <= $min) {
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return array_chunk(
|
||||
array_map(
|
||||
function () use ($min, $max, $wholeNumber): int|float {
|
||||
return $wholeNumber
|
||||
? mt_rand((int) $min, (int) $max)
|
||||
: (mt_rand() / mt_getrandmax()) * ($max - $min) + $min;
|
||||
},
|
||||
array_fill(0, $rows * $columns, $min)
|
||||
),
|
||||
max($columns, 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
846
lib/PhpSpreadsheet/Calculation/MathTrig/Roman.php
Normal file
846
lib/PhpSpreadsheet/Calculation/MathTrig/Roman.php
Normal file
|
|
@ -0,0 +1,846 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Roman
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
private const VALUES = [
|
||||
45 => ['VL'],
|
||||
46 => ['VLI'],
|
||||
47 => ['VLII'],
|
||||
48 => ['VLIII'],
|
||||
49 => ['VLIV', 'IL'],
|
||||
95 => ['VC'],
|
||||
96 => ['VCI'],
|
||||
97 => ['VCII'],
|
||||
98 => ['VCIII'],
|
||||
99 => ['VCIV', 'IC'],
|
||||
145 => ['CVL'],
|
||||
146 => ['CVLI'],
|
||||
147 => ['CVLII'],
|
||||
148 => ['CVLIII'],
|
||||
149 => ['CVLIV', 'CIL'],
|
||||
195 => ['CVC'],
|
||||
196 => ['CVCI'],
|
||||
197 => ['CVCII'],
|
||||
198 => ['CVCIII'],
|
||||
199 => ['CVCIV', 'CIC'],
|
||||
245 => ['CCVL'],
|
||||
246 => ['CCVLI'],
|
||||
247 => ['CCVLII'],
|
||||
248 => ['CCVLIII'],
|
||||
249 => ['CCVLIV', 'CCIL'],
|
||||
295 => ['CCVC'],
|
||||
296 => ['CCVCI'],
|
||||
297 => ['CCVCII'],
|
||||
298 => ['CCVCIII'],
|
||||
299 => ['CCVCIV', 'CCIC'],
|
||||
345 => ['CCCVL'],
|
||||
346 => ['CCCVLI'],
|
||||
347 => ['CCCVLII'],
|
||||
348 => ['CCCVLIII'],
|
||||
349 => ['CCCVLIV', 'CCCIL'],
|
||||
395 => ['CCCVC'],
|
||||
396 => ['CCCVCI'],
|
||||
397 => ['CCCVCII'],
|
||||
398 => ['CCCVCIII'],
|
||||
399 => ['CCCVCIV', 'CCCIC'],
|
||||
445 => ['CDVL'],
|
||||
446 => ['CDVLI'],
|
||||
447 => ['CDVLII'],
|
||||
448 => ['CDVLIII'],
|
||||
449 => ['CDVLIV', 'CDIL'],
|
||||
450 => ['LD'],
|
||||
451 => ['LDI'],
|
||||
452 => ['LDII'],
|
||||
453 => ['LDIII'],
|
||||
454 => ['LDIV'],
|
||||
455 => ['LDV'],
|
||||
456 => ['LDVI'],
|
||||
457 => ['LDVII'],
|
||||
458 => ['LDVIII'],
|
||||
459 => ['LDIX'],
|
||||
460 => ['LDX'],
|
||||
461 => ['LDXI'],
|
||||
462 => ['LDXII'],
|
||||
463 => ['LDXIII'],
|
||||
464 => ['LDXIV'],
|
||||
465 => ['LDXV'],
|
||||
466 => ['LDXVI'],
|
||||
467 => ['LDXVII'],
|
||||
468 => ['LDXVIII'],
|
||||
469 => ['LDXIX'],
|
||||
470 => ['LDXX'],
|
||||
471 => ['LDXXI'],
|
||||
472 => ['LDXXII'],
|
||||
473 => ['LDXXIII'],
|
||||
474 => ['LDXXIV'],
|
||||
475 => ['LDXXV'],
|
||||
476 => ['LDXXVI'],
|
||||
477 => ['LDXXVII'],
|
||||
478 => ['LDXXVIII'],
|
||||
479 => ['LDXXIX'],
|
||||
480 => ['LDXXX'],
|
||||
481 => ['LDXXXI'],
|
||||
482 => ['LDXXXII'],
|
||||
483 => ['LDXXXIII'],
|
||||
484 => ['LDXXXIV'],
|
||||
485 => ['LDXXXV'],
|
||||
486 => ['LDXXXVI'],
|
||||
487 => ['LDXXXVII'],
|
||||
488 => ['LDXXXVIII'],
|
||||
489 => ['LDXXXIX'],
|
||||
490 => ['LDXL', 'XD'],
|
||||
491 => ['LDXLI', 'XDI'],
|
||||
492 => ['LDXLII', 'XDII'],
|
||||
493 => ['LDXLIII', 'XDIII'],
|
||||
494 => ['LDXLIV', 'XDIV'],
|
||||
495 => ['LDVL', 'XDV', 'VD'],
|
||||
496 => ['LDVLI', 'XDVI', 'VDI'],
|
||||
497 => ['LDVLII', 'XDVII', 'VDII'],
|
||||
498 => ['LDVLIII', 'XDVIII', 'VDIII'],
|
||||
499 => ['LDVLIV', 'XDIX', 'VDIV', 'ID'],
|
||||
545 => ['DVL'],
|
||||
546 => ['DVLI'],
|
||||
547 => ['DVLII'],
|
||||
548 => ['DVLIII'],
|
||||
549 => ['DVLIV', 'DIL'],
|
||||
595 => ['DVC'],
|
||||
596 => ['DVCI'],
|
||||
597 => ['DVCII'],
|
||||
598 => ['DVCIII'],
|
||||
599 => ['DVCIV', 'DIC'],
|
||||
645 => ['DCVL'],
|
||||
646 => ['DCVLI'],
|
||||
647 => ['DCVLII'],
|
||||
648 => ['DCVLIII'],
|
||||
649 => ['DCVLIV', 'DCIL'],
|
||||
695 => ['DCVC'],
|
||||
696 => ['DCVCI'],
|
||||
697 => ['DCVCII'],
|
||||
698 => ['DCVCIII'],
|
||||
699 => ['DCVCIV', 'DCIC'],
|
||||
745 => ['DCCVL'],
|
||||
746 => ['DCCVLI'],
|
||||
747 => ['DCCVLII'],
|
||||
748 => ['DCCVLIII'],
|
||||
749 => ['DCCVLIV', 'DCCIL'],
|
||||
795 => ['DCCVC'],
|
||||
796 => ['DCCVCI'],
|
||||
797 => ['DCCVCII'],
|
||||
798 => ['DCCVCIII'],
|
||||
799 => ['DCCVCIV', 'DCCIC'],
|
||||
845 => ['DCCCVL'],
|
||||
846 => ['DCCCVLI'],
|
||||
847 => ['DCCCVLII'],
|
||||
848 => ['DCCCVLIII'],
|
||||
849 => ['DCCCVLIV', 'DCCCIL'],
|
||||
895 => ['DCCCVC'],
|
||||
896 => ['DCCCVCI'],
|
||||
897 => ['DCCCVCII'],
|
||||
898 => ['DCCCVCIII'],
|
||||
899 => ['DCCCVCIV', 'DCCCIC'],
|
||||
945 => ['CMVL'],
|
||||
946 => ['CMVLI'],
|
||||
947 => ['CMVLII'],
|
||||
948 => ['CMVLIII'],
|
||||
949 => ['CMVLIV', 'CMIL'],
|
||||
950 => ['LM'],
|
||||
951 => ['LMI'],
|
||||
952 => ['LMII'],
|
||||
953 => ['LMIII'],
|
||||
954 => ['LMIV'],
|
||||
955 => ['LMV'],
|
||||
956 => ['LMVI'],
|
||||
957 => ['LMVII'],
|
||||
958 => ['LMVIII'],
|
||||
959 => ['LMIX'],
|
||||
960 => ['LMX'],
|
||||
961 => ['LMXI'],
|
||||
962 => ['LMXII'],
|
||||
963 => ['LMXIII'],
|
||||
964 => ['LMXIV'],
|
||||
965 => ['LMXV'],
|
||||
966 => ['LMXVI'],
|
||||
967 => ['LMXVII'],
|
||||
968 => ['LMXVIII'],
|
||||
969 => ['LMXIX'],
|
||||
970 => ['LMXX'],
|
||||
971 => ['LMXXI'],
|
||||
972 => ['LMXXII'],
|
||||
973 => ['LMXXIII'],
|
||||
974 => ['LMXXIV'],
|
||||
975 => ['LMXXV'],
|
||||
976 => ['LMXXVI'],
|
||||
977 => ['LMXXVII'],
|
||||
978 => ['LMXXVIII'],
|
||||
979 => ['LMXXIX'],
|
||||
980 => ['LMXXX'],
|
||||
981 => ['LMXXXI'],
|
||||
982 => ['LMXXXII'],
|
||||
983 => ['LMXXXIII'],
|
||||
984 => ['LMXXXIV'],
|
||||
985 => ['LMXXXV'],
|
||||
986 => ['LMXXXVI'],
|
||||
987 => ['LMXXXVII'],
|
||||
988 => ['LMXXXVIII'],
|
||||
989 => ['LMXXXIX'],
|
||||
990 => ['LMXL', 'XM'],
|
||||
991 => ['LMXLI', 'XMI'],
|
||||
992 => ['LMXLII', 'XMII'],
|
||||
993 => ['LMXLIII', 'XMIII'],
|
||||
994 => ['LMXLIV', 'XMIV'],
|
||||
995 => ['LMVL', 'XMV', 'VM'],
|
||||
996 => ['LMVLI', 'XMVI', 'VMI'],
|
||||
997 => ['LMVLII', 'XMVII', 'VMII'],
|
||||
998 => ['LMVLIII', 'XMVIII', 'VMIII'],
|
||||
999 => ['LMVLIV', 'XMIX', 'VMIV', 'IM'],
|
||||
1045 => ['MVL'],
|
||||
1046 => ['MVLI'],
|
||||
1047 => ['MVLII'],
|
||||
1048 => ['MVLIII'],
|
||||
1049 => ['MVLIV', 'MIL'],
|
||||
1095 => ['MVC'],
|
||||
1096 => ['MVCI'],
|
||||
1097 => ['MVCII'],
|
||||
1098 => ['MVCIII'],
|
||||
1099 => ['MVCIV', 'MIC'],
|
||||
1145 => ['MCVL'],
|
||||
1146 => ['MCVLI'],
|
||||
1147 => ['MCVLII'],
|
||||
1148 => ['MCVLIII'],
|
||||
1149 => ['MCVLIV', 'MCIL'],
|
||||
1195 => ['MCVC'],
|
||||
1196 => ['MCVCI'],
|
||||
1197 => ['MCVCII'],
|
||||
1198 => ['MCVCIII'],
|
||||
1199 => ['MCVCIV', 'MCIC'],
|
||||
1245 => ['MCCVL'],
|
||||
1246 => ['MCCVLI'],
|
||||
1247 => ['MCCVLII'],
|
||||
1248 => ['MCCVLIII'],
|
||||
1249 => ['MCCVLIV', 'MCCIL'],
|
||||
1295 => ['MCCVC'],
|
||||
1296 => ['MCCVCI'],
|
||||
1297 => ['MCCVCII'],
|
||||
1298 => ['MCCVCIII'],
|
||||
1299 => ['MCCVCIV', 'MCCIC'],
|
||||
1345 => ['MCCCVL'],
|
||||
1346 => ['MCCCVLI'],
|
||||
1347 => ['MCCCVLII'],
|
||||
1348 => ['MCCCVLIII'],
|
||||
1349 => ['MCCCVLIV', 'MCCCIL'],
|
||||
1395 => ['MCCCVC'],
|
||||
1396 => ['MCCCVCI'],
|
||||
1397 => ['MCCCVCII'],
|
||||
1398 => ['MCCCVCIII'],
|
||||
1399 => ['MCCCVCIV', 'MCCCIC'],
|
||||
1445 => ['MCDVL'],
|
||||
1446 => ['MCDVLI'],
|
||||
1447 => ['MCDVLII'],
|
||||
1448 => ['MCDVLIII'],
|
||||
1449 => ['MCDVLIV', 'MCDIL'],
|
||||
1450 => ['MLD'],
|
||||
1451 => ['MLDI'],
|
||||
1452 => ['MLDII'],
|
||||
1453 => ['MLDIII'],
|
||||
1454 => ['MLDIV'],
|
||||
1455 => ['MLDV'],
|
||||
1456 => ['MLDVI'],
|
||||
1457 => ['MLDVII'],
|
||||
1458 => ['MLDVIII'],
|
||||
1459 => ['MLDIX'],
|
||||
1460 => ['MLDX'],
|
||||
1461 => ['MLDXI'],
|
||||
1462 => ['MLDXII'],
|
||||
1463 => ['MLDXIII'],
|
||||
1464 => ['MLDXIV'],
|
||||
1465 => ['MLDXV'],
|
||||
1466 => ['MLDXVI'],
|
||||
1467 => ['MLDXVII'],
|
||||
1468 => ['MLDXVIII'],
|
||||
1469 => ['MLDXIX'],
|
||||
1470 => ['MLDXX'],
|
||||
1471 => ['MLDXXI'],
|
||||
1472 => ['MLDXXII'],
|
||||
1473 => ['MLDXXIII'],
|
||||
1474 => ['MLDXXIV'],
|
||||
1475 => ['MLDXXV'],
|
||||
1476 => ['MLDXXVI'],
|
||||
1477 => ['MLDXXVII'],
|
||||
1478 => ['MLDXXVIII'],
|
||||
1479 => ['MLDXXIX'],
|
||||
1480 => ['MLDXXX'],
|
||||
1481 => ['MLDXXXI'],
|
||||
1482 => ['MLDXXXII'],
|
||||
1483 => ['MLDXXXIII'],
|
||||
1484 => ['MLDXXXIV'],
|
||||
1485 => ['MLDXXXV'],
|
||||
1486 => ['MLDXXXVI'],
|
||||
1487 => ['MLDXXXVII'],
|
||||
1488 => ['MLDXXXVIII'],
|
||||
1489 => ['MLDXXXIX'],
|
||||
1490 => ['MLDXL', 'MXD'],
|
||||
1491 => ['MLDXLI', 'MXDI'],
|
||||
1492 => ['MLDXLII', 'MXDII'],
|
||||
1493 => ['MLDXLIII', 'MXDIII'],
|
||||
1494 => ['MLDXLIV', 'MXDIV'],
|
||||
1495 => ['MLDVL', 'MXDV', 'MVD'],
|
||||
1496 => ['MLDVLI', 'MXDVI', 'MVDI'],
|
||||
1497 => ['MLDVLII', 'MXDVII', 'MVDII'],
|
||||
1498 => ['MLDVLIII', 'MXDVIII', 'MVDIII'],
|
||||
1499 => ['MLDVLIV', 'MXDIX', 'MVDIV', 'MID'],
|
||||
1545 => ['MDVL'],
|
||||
1546 => ['MDVLI'],
|
||||
1547 => ['MDVLII'],
|
||||
1548 => ['MDVLIII'],
|
||||
1549 => ['MDVLIV', 'MDIL'],
|
||||
1595 => ['MDVC'],
|
||||
1596 => ['MDVCI'],
|
||||
1597 => ['MDVCII'],
|
||||
1598 => ['MDVCIII'],
|
||||
1599 => ['MDVCIV', 'MDIC'],
|
||||
1645 => ['MDCVL'],
|
||||
1646 => ['MDCVLI'],
|
||||
1647 => ['MDCVLII'],
|
||||
1648 => ['MDCVLIII'],
|
||||
1649 => ['MDCVLIV', 'MDCIL'],
|
||||
1695 => ['MDCVC'],
|
||||
1696 => ['MDCVCI'],
|
||||
1697 => ['MDCVCII'],
|
||||
1698 => ['MDCVCIII'],
|
||||
1699 => ['MDCVCIV', 'MDCIC'],
|
||||
1745 => ['MDCCVL'],
|
||||
1746 => ['MDCCVLI'],
|
||||
1747 => ['MDCCVLII'],
|
||||
1748 => ['MDCCVLIII'],
|
||||
1749 => ['MDCCVLIV', 'MDCCIL'],
|
||||
1795 => ['MDCCVC'],
|
||||
1796 => ['MDCCVCI'],
|
||||
1797 => ['MDCCVCII'],
|
||||
1798 => ['MDCCVCIII'],
|
||||
1799 => ['MDCCVCIV', 'MDCCIC'],
|
||||
1845 => ['MDCCCVL'],
|
||||
1846 => ['MDCCCVLI'],
|
||||
1847 => ['MDCCCVLII'],
|
||||
1848 => ['MDCCCVLIII'],
|
||||
1849 => ['MDCCCVLIV', 'MDCCCIL'],
|
||||
1895 => ['MDCCCVC'],
|
||||
1896 => ['MDCCCVCI'],
|
||||
1897 => ['MDCCCVCII'],
|
||||
1898 => ['MDCCCVCIII'],
|
||||
1899 => ['MDCCCVCIV', 'MDCCCIC'],
|
||||
1945 => ['MCMVL'],
|
||||
1946 => ['MCMVLI'],
|
||||
1947 => ['MCMVLII'],
|
||||
1948 => ['MCMVLIII'],
|
||||
1949 => ['MCMVLIV', 'MCMIL'],
|
||||
1950 => ['MLM'],
|
||||
1951 => ['MLMI'],
|
||||
1952 => ['MLMII'],
|
||||
1953 => ['MLMIII'],
|
||||
1954 => ['MLMIV'],
|
||||
1955 => ['MLMV'],
|
||||
1956 => ['MLMVI'],
|
||||
1957 => ['MLMVII'],
|
||||
1958 => ['MLMVIII'],
|
||||
1959 => ['MLMIX'],
|
||||
1960 => ['MLMX'],
|
||||
1961 => ['MLMXI'],
|
||||
1962 => ['MLMXII'],
|
||||
1963 => ['MLMXIII'],
|
||||
1964 => ['MLMXIV'],
|
||||
1965 => ['MLMXV'],
|
||||
1966 => ['MLMXVI'],
|
||||
1967 => ['MLMXVII'],
|
||||
1968 => ['MLMXVIII'],
|
||||
1969 => ['MLMXIX'],
|
||||
1970 => ['MLMXX'],
|
||||
1971 => ['MLMXXI'],
|
||||
1972 => ['MLMXXII'],
|
||||
1973 => ['MLMXXIII'],
|
||||
1974 => ['MLMXXIV'],
|
||||
1975 => ['MLMXXV'],
|
||||
1976 => ['MLMXXVI'],
|
||||
1977 => ['MLMXXVII'],
|
||||
1978 => ['MLMXXVIII'],
|
||||
1979 => ['MLMXXIX'],
|
||||
1980 => ['MLMXXX'],
|
||||
1981 => ['MLMXXXI'],
|
||||
1982 => ['MLMXXXII'],
|
||||
1983 => ['MLMXXXIII'],
|
||||
1984 => ['MLMXXXIV'],
|
||||
1985 => ['MLMXXXV'],
|
||||
1986 => ['MLMXXXVI'],
|
||||
1987 => ['MLMXXXVII'],
|
||||
1988 => ['MLMXXXVIII'],
|
||||
1989 => ['MLMXXXIX'],
|
||||
1990 => ['MLMXL', 'MXM'],
|
||||
1991 => ['MLMXLI', 'MXMI'],
|
||||
1992 => ['MLMXLII', 'MXMII'],
|
||||
1993 => ['MLMXLIII', 'MXMIII'],
|
||||
1994 => ['MLMXLIV', 'MXMIV'],
|
||||
1995 => ['MLMVL', 'MXMV', 'MVM'],
|
||||
1996 => ['MLMVLI', 'MXMVI', 'MVMI'],
|
||||
1997 => ['MLMVLII', 'MXMVII', 'MVMII'],
|
||||
1998 => ['MLMVLIII', 'MXMVIII', 'MVMIII'],
|
||||
1999 => ['MLMVLIV', 'MXMIX', 'MVMIV', 'MIM'],
|
||||
2045 => ['MMVL'],
|
||||
2046 => ['MMVLI'],
|
||||
2047 => ['MMVLII'],
|
||||
2048 => ['MMVLIII'],
|
||||
2049 => ['MMVLIV', 'MMIL'],
|
||||
2095 => ['MMVC'],
|
||||
2096 => ['MMVCI'],
|
||||
2097 => ['MMVCII'],
|
||||
2098 => ['MMVCIII'],
|
||||
2099 => ['MMVCIV', 'MMIC'],
|
||||
2145 => ['MMCVL'],
|
||||
2146 => ['MMCVLI'],
|
||||
2147 => ['MMCVLII'],
|
||||
2148 => ['MMCVLIII'],
|
||||
2149 => ['MMCVLIV', 'MMCIL'],
|
||||
2195 => ['MMCVC'],
|
||||
2196 => ['MMCVCI'],
|
||||
2197 => ['MMCVCII'],
|
||||
2198 => ['MMCVCIII'],
|
||||
2199 => ['MMCVCIV', 'MMCIC'],
|
||||
2245 => ['MMCCVL'],
|
||||
2246 => ['MMCCVLI'],
|
||||
2247 => ['MMCCVLII'],
|
||||
2248 => ['MMCCVLIII'],
|
||||
2249 => ['MMCCVLIV', 'MMCCIL'],
|
||||
2295 => ['MMCCVC'],
|
||||
2296 => ['MMCCVCI'],
|
||||
2297 => ['MMCCVCII'],
|
||||
2298 => ['MMCCVCIII'],
|
||||
2299 => ['MMCCVCIV', 'MMCCIC'],
|
||||
2345 => ['MMCCCVL'],
|
||||
2346 => ['MMCCCVLI'],
|
||||
2347 => ['MMCCCVLII'],
|
||||
2348 => ['MMCCCVLIII'],
|
||||
2349 => ['MMCCCVLIV', 'MMCCCIL'],
|
||||
2395 => ['MMCCCVC'],
|
||||
2396 => ['MMCCCVCI'],
|
||||
2397 => ['MMCCCVCII'],
|
||||
2398 => ['MMCCCVCIII'],
|
||||
2399 => ['MMCCCVCIV', 'MMCCCIC'],
|
||||
2445 => ['MMCDVL'],
|
||||
2446 => ['MMCDVLI'],
|
||||
2447 => ['MMCDVLII'],
|
||||
2448 => ['MMCDVLIII'],
|
||||
2449 => ['MMCDVLIV', 'MMCDIL'],
|
||||
2450 => ['MMLD'],
|
||||
2451 => ['MMLDI'],
|
||||
2452 => ['MMLDII'],
|
||||
2453 => ['MMLDIII'],
|
||||
2454 => ['MMLDIV'],
|
||||
2455 => ['MMLDV'],
|
||||
2456 => ['MMLDVI'],
|
||||
2457 => ['MMLDVII'],
|
||||
2458 => ['MMLDVIII'],
|
||||
2459 => ['MMLDIX'],
|
||||
2460 => ['MMLDX'],
|
||||
2461 => ['MMLDXI'],
|
||||
2462 => ['MMLDXII'],
|
||||
2463 => ['MMLDXIII'],
|
||||
2464 => ['MMLDXIV'],
|
||||
2465 => ['MMLDXV'],
|
||||
2466 => ['MMLDXVI'],
|
||||
2467 => ['MMLDXVII'],
|
||||
2468 => ['MMLDXVIII'],
|
||||
2469 => ['MMLDXIX'],
|
||||
2470 => ['MMLDXX'],
|
||||
2471 => ['MMLDXXI'],
|
||||
2472 => ['MMLDXXII'],
|
||||
2473 => ['MMLDXXIII'],
|
||||
2474 => ['MMLDXXIV'],
|
||||
2475 => ['MMLDXXV'],
|
||||
2476 => ['MMLDXXVI'],
|
||||
2477 => ['MMLDXXVII'],
|
||||
2478 => ['MMLDXXVIII'],
|
||||
2479 => ['MMLDXXIX'],
|
||||
2480 => ['MMLDXXX'],
|
||||
2481 => ['MMLDXXXI'],
|
||||
2482 => ['MMLDXXXII'],
|
||||
2483 => ['MMLDXXXIII'],
|
||||
2484 => ['MMLDXXXIV'],
|
||||
2485 => ['MMLDXXXV'],
|
||||
2486 => ['MMLDXXXVI'],
|
||||
2487 => ['MMLDXXXVII'],
|
||||
2488 => ['MMLDXXXVIII'],
|
||||
2489 => ['MMLDXXXIX'],
|
||||
2490 => ['MMLDXL', 'MMXD'],
|
||||
2491 => ['MMLDXLI', 'MMXDI'],
|
||||
2492 => ['MMLDXLII', 'MMXDII'],
|
||||
2493 => ['MMLDXLIII', 'MMXDIII'],
|
||||
2494 => ['MMLDXLIV', 'MMXDIV'],
|
||||
2495 => ['MMLDVL', 'MMXDV', 'MMVD'],
|
||||
2496 => ['MMLDVLI', 'MMXDVI', 'MMVDI'],
|
||||
2497 => ['MMLDVLII', 'MMXDVII', 'MMVDII'],
|
||||
2498 => ['MMLDVLIII', 'MMXDVIII', 'MMVDIII'],
|
||||
2499 => ['MMLDVLIV', 'MMXDIX', 'MMVDIV', 'MMID'],
|
||||
2545 => ['MMDVL'],
|
||||
2546 => ['MMDVLI'],
|
||||
2547 => ['MMDVLII'],
|
||||
2548 => ['MMDVLIII'],
|
||||
2549 => ['MMDVLIV', 'MMDIL'],
|
||||
2595 => ['MMDVC'],
|
||||
2596 => ['MMDVCI'],
|
||||
2597 => ['MMDVCII'],
|
||||
2598 => ['MMDVCIII'],
|
||||
2599 => ['MMDVCIV', 'MMDIC'],
|
||||
2645 => ['MMDCVL'],
|
||||
2646 => ['MMDCVLI'],
|
||||
2647 => ['MMDCVLII'],
|
||||
2648 => ['MMDCVLIII'],
|
||||
2649 => ['MMDCVLIV', 'MMDCIL'],
|
||||
2695 => ['MMDCVC'],
|
||||
2696 => ['MMDCVCI'],
|
||||
2697 => ['MMDCVCII'],
|
||||
2698 => ['MMDCVCIII'],
|
||||
2699 => ['MMDCVCIV', 'MMDCIC'],
|
||||
2745 => ['MMDCCVL'],
|
||||
2746 => ['MMDCCVLI'],
|
||||
2747 => ['MMDCCVLII'],
|
||||
2748 => ['MMDCCVLIII'],
|
||||
2749 => ['MMDCCVLIV', 'MMDCCIL'],
|
||||
2795 => ['MMDCCVC'],
|
||||
2796 => ['MMDCCVCI'],
|
||||
2797 => ['MMDCCVCII'],
|
||||
2798 => ['MMDCCVCIII'],
|
||||
2799 => ['MMDCCVCIV', 'MMDCCIC'],
|
||||
2845 => ['MMDCCCVL'],
|
||||
2846 => ['MMDCCCVLI'],
|
||||
2847 => ['MMDCCCVLII'],
|
||||
2848 => ['MMDCCCVLIII'],
|
||||
2849 => ['MMDCCCVLIV', 'MMDCCCIL'],
|
||||
2895 => ['MMDCCCVC'],
|
||||
2896 => ['MMDCCCVCI'],
|
||||
2897 => ['MMDCCCVCII'],
|
||||
2898 => ['MMDCCCVCIII'],
|
||||
2899 => ['MMDCCCVCIV', 'MMDCCCIC'],
|
||||
2945 => ['MMCMVL'],
|
||||
2946 => ['MMCMVLI'],
|
||||
2947 => ['MMCMVLII'],
|
||||
2948 => ['MMCMVLIII'],
|
||||
2949 => ['MMCMVLIV', 'MMCMIL'],
|
||||
2950 => ['MMLM'],
|
||||
2951 => ['MMLMI'],
|
||||
2952 => ['MMLMII'],
|
||||
2953 => ['MMLMIII'],
|
||||
2954 => ['MMLMIV'],
|
||||
2955 => ['MMLMV'],
|
||||
2956 => ['MMLMVI'],
|
||||
2957 => ['MMLMVII'],
|
||||
2958 => ['MMLMVIII'],
|
||||
2959 => ['MMLMIX'],
|
||||
2960 => ['MMLMX'],
|
||||
2961 => ['MMLMXI'],
|
||||
2962 => ['MMLMXII'],
|
||||
2963 => ['MMLMXIII'],
|
||||
2964 => ['MMLMXIV'],
|
||||
2965 => ['MMLMXV'],
|
||||
2966 => ['MMLMXVI'],
|
||||
2967 => ['MMLMXVII'],
|
||||
2968 => ['MMLMXVIII'],
|
||||
2969 => ['MMLMXIX'],
|
||||
2970 => ['MMLMXX'],
|
||||
2971 => ['MMLMXXI'],
|
||||
2972 => ['MMLMXXII'],
|
||||
2973 => ['MMLMXXIII'],
|
||||
2974 => ['MMLMXXIV'],
|
||||
2975 => ['MMLMXXV'],
|
||||
2976 => ['MMLMXXVI'],
|
||||
2977 => ['MMLMXXVII'],
|
||||
2978 => ['MMLMXXVIII'],
|
||||
2979 => ['MMLMXXIX'],
|
||||
2980 => ['MMLMXXX'],
|
||||
2981 => ['MMLMXXXI'],
|
||||
2982 => ['MMLMXXXII'],
|
||||
2983 => ['MMLMXXXIII'],
|
||||
2984 => ['MMLMXXXIV'],
|
||||
2985 => ['MMLMXXXV'],
|
||||
2986 => ['MMLMXXXVI'],
|
||||
2987 => ['MMLMXXXVII'],
|
||||
2988 => ['MMLMXXXVIII'],
|
||||
2989 => ['MMLMXXXIX'],
|
||||
2990 => ['MMLMXL', 'MMXM'],
|
||||
2991 => ['MMLMXLI', 'MMXMI'],
|
||||
2992 => ['MMLMXLII', 'MMXMII'],
|
||||
2993 => ['MMLMXLIII', 'MMXMIII'],
|
||||
2994 => ['MMLMXLIV', 'MMXMIV'],
|
||||
2995 => ['MMLMVL', 'MMXMV', 'MMVM'],
|
||||
2996 => ['MMLMVLI', 'MMXMVI', 'MMVMI'],
|
||||
2997 => ['MMLMVLII', 'MMXMVII', 'MMVMII'],
|
||||
2998 => ['MMLMVLIII', 'MMXMVIII', 'MMVMIII'],
|
||||
2999 => ['MMLMVLIV', 'MMXMIX', 'MMVMIV', 'MMIM'],
|
||||
3045 => ['MMMVL'],
|
||||
3046 => ['MMMVLI'],
|
||||
3047 => ['MMMVLII'],
|
||||
3048 => ['MMMVLIII'],
|
||||
3049 => ['MMMVLIV', 'MMMIL'],
|
||||
3095 => ['MMMVC'],
|
||||
3096 => ['MMMVCI'],
|
||||
3097 => ['MMMVCII'],
|
||||
3098 => ['MMMVCIII'],
|
||||
3099 => ['MMMVCIV', 'MMMIC'],
|
||||
3145 => ['MMMCVL'],
|
||||
3146 => ['MMMCVLI'],
|
||||
3147 => ['MMMCVLII'],
|
||||
3148 => ['MMMCVLIII'],
|
||||
3149 => ['MMMCVLIV', 'MMMCIL'],
|
||||
3195 => ['MMMCVC'],
|
||||
3196 => ['MMMCVCI'],
|
||||
3197 => ['MMMCVCII'],
|
||||
3198 => ['MMMCVCIII'],
|
||||
3199 => ['MMMCVCIV', 'MMMCIC'],
|
||||
3245 => ['MMMCCVL'],
|
||||
3246 => ['MMMCCVLI'],
|
||||
3247 => ['MMMCCVLII'],
|
||||
3248 => ['MMMCCVLIII'],
|
||||
3249 => ['MMMCCVLIV', 'MMMCCIL'],
|
||||
3295 => ['MMMCCVC'],
|
||||
3296 => ['MMMCCVCI'],
|
||||
3297 => ['MMMCCVCII'],
|
||||
3298 => ['MMMCCVCIII'],
|
||||
3299 => ['MMMCCVCIV', 'MMMCCIC'],
|
||||
3345 => ['MMMCCCVL'],
|
||||
3346 => ['MMMCCCVLI'],
|
||||
3347 => ['MMMCCCVLII'],
|
||||
3348 => ['MMMCCCVLIII'],
|
||||
3349 => ['MMMCCCVLIV', 'MMMCCCIL'],
|
||||
3395 => ['MMMCCCVC'],
|
||||
3396 => ['MMMCCCVCI'],
|
||||
3397 => ['MMMCCCVCII'],
|
||||
3398 => ['MMMCCCVCIII'],
|
||||
3399 => ['MMMCCCVCIV', 'MMMCCCIC'],
|
||||
3445 => ['MMMCDVL'],
|
||||
3446 => ['MMMCDVLI'],
|
||||
3447 => ['MMMCDVLII'],
|
||||
3448 => ['MMMCDVLIII'],
|
||||
3449 => ['MMMCDVLIV', 'MMMCDIL'],
|
||||
3450 => ['MMMLD'],
|
||||
3451 => ['MMMLDI'],
|
||||
3452 => ['MMMLDII'],
|
||||
3453 => ['MMMLDIII'],
|
||||
3454 => ['MMMLDIV'],
|
||||
3455 => ['MMMLDV'],
|
||||
3456 => ['MMMLDVI'],
|
||||
3457 => ['MMMLDVII'],
|
||||
3458 => ['MMMLDVIII'],
|
||||
3459 => ['MMMLDIX'],
|
||||
3460 => ['MMMLDX'],
|
||||
3461 => ['MMMLDXI'],
|
||||
3462 => ['MMMLDXII'],
|
||||
3463 => ['MMMLDXIII'],
|
||||
3464 => ['MMMLDXIV'],
|
||||
3465 => ['MMMLDXV'],
|
||||
3466 => ['MMMLDXVI'],
|
||||
3467 => ['MMMLDXVII'],
|
||||
3468 => ['MMMLDXVIII'],
|
||||
3469 => ['MMMLDXIX'],
|
||||
3470 => ['MMMLDXX'],
|
||||
3471 => ['MMMLDXXI'],
|
||||
3472 => ['MMMLDXXII'],
|
||||
3473 => ['MMMLDXXIII'],
|
||||
3474 => ['MMMLDXXIV'],
|
||||
3475 => ['MMMLDXXV'],
|
||||
3476 => ['MMMLDXXVI'],
|
||||
3477 => ['MMMLDXXVII'],
|
||||
3478 => ['MMMLDXXVIII'],
|
||||
3479 => ['MMMLDXXIX'],
|
||||
3480 => ['MMMLDXXX'],
|
||||
3481 => ['MMMLDXXXI'],
|
||||
3482 => ['MMMLDXXXII'],
|
||||
3483 => ['MMMLDXXXIII'],
|
||||
3484 => ['MMMLDXXXIV'],
|
||||
3485 => ['MMMLDXXXV'],
|
||||
3486 => ['MMMLDXXXVI'],
|
||||
3487 => ['MMMLDXXXVII'],
|
||||
3488 => ['MMMLDXXXVIII'],
|
||||
3489 => ['MMMLDXXXIX'],
|
||||
3490 => ['MMMLDXL', 'MMMXD'],
|
||||
3491 => ['MMMLDXLI', 'MMMXDI'],
|
||||
3492 => ['MMMLDXLII', 'MMMXDII'],
|
||||
3493 => ['MMMLDXLIII', 'MMMXDIII'],
|
||||
3494 => ['MMMLDXLIV', 'MMMXDIV'],
|
||||
3495 => ['MMMLDVL', 'MMMXDV', 'MMMVD'],
|
||||
3496 => ['MMMLDVLI', 'MMMXDVI', 'MMMVDI'],
|
||||
3497 => ['MMMLDVLII', 'MMMXDVII', 'MMMVDII'],
|
||||
3498 => ['MMMLDVLIII', 'MMMXDVIII', 'MMMVDIII'],
|
||||
3499 => ['MMMLDVLIV', 'MMMXDIX', 'MMMVDIV', 'MMMID'],
|
||||
3545 => ['MMMDVL'],
|
||||
3546 => ['MMMDVLI'],
|
||||
3547 => ['MMMDVLII'],
|
||||
3548 => ['MMMDVLIII'],
|
||||
3549 => ['MMMDVLIV', 'MMMDIL'],
|
||||
3595 => ['MMMDVC'],
|
||||
3596 => ['MMMDVCI'],
|
||||
3597 => ['MMMDVCII'],
|
||||
3598 => ['MMMDVCIII'],
|
||||
3599 => ['MMMDVCIV', 'MMMDIC'],
|
||||
3645 => ['MMMDCVL'],
|
||||
3646 => ['MMMDCVLI'],
|
||||
3647 => ['MMMDCVLII'],
|
||||
3648 => ['MMMDCVLIII'],
|
||||
3649 => ['MMMDCVLIV', 'MMMDCIL'],
|
||||
3695 => ['MMMDCVC'],
|
||||
3696 => ['MMMDCVCI'],
|
||||
3697 => ['MMMDCVCII'],
|
||||
3698 => ['MMMDCVCIII'],
|
||||
3699 => ['MMMDCVCIV', 'MMMDCIC'],
|
||||
3745 => ['MMMDCCVL'],
|
||||
3746 => ['MMMDCCVLI'],
|
||||
3747 => ['MMMDCCVLII'],
|
||||
3748 => ['MMMDCCVLIII'],
|
||||
3749 => ['MMMDCCVLIV', 'MMMDCCIL'],
|
||||
3795 => ['MMMDCCVC'],
|
||||
3796 => ['MMMDCCVCI'],
|
||||
3797 => ['MMMDCCVCII'],
|
||||
3798 => ['MMMDCCVCIII'],
|
||||
3799 => ['MMMDCCVCIV', 'MMMDCCIC'],
|
||||
3845 => ['MMMDCCCVL'],
|
||||
3846 => ['MMMDCCCVLI'],
|
||||
3847 => ['MMMDCCCVLII'],
|
||||
3848 => ['MMMDCCCVLIII'],
|
||||
3849 => ['MMMDCCCVLIV', 'MMMDCCCIL'],
|
||||
3895 => ['MMMDCCCVC'],
|
||||
3896 => ['MMMDCCCVCI'],
|
||||
3897 => ['MMMDCCCVCII'],
|
||||
3898 => ['MMMDCCCVCIII'],
|
||||
3899 => ['MMMDCCCVCIV', 'MMMDCCCIC'],
|
||||
3945 => ['MMMCMVL'],
|
||||
3946 => ['MMMCMVLI'],
|
||||
3947 => ['MMMCMVLII'],
|
||||
3948 => ['MMMCMVLIII'],
|
||||
3949 => ['MMMCMVLIV', 'MMMCMIL'],
|
||||
3950 => ['MMMLM'],
|
||||
3951 => ['MMMLMI'],
|
||||
3952 => ['MMMLMII'],
|
||||
3953 => ['MMMLMIII'],
|
||||
3954 => ['MMMLMIV'],
|
||||
3955 => ['MMMLMV'],
|
||||
3956 => ['MMMLMVI'],
|
||||
3957 => ['MMMLMVII'],
|
||||
3958 => ['MMMLMVIII'],
|
||||
3959 => ['MMMLMIX'],
|
||||
3960 => ['MMMLMX'],
|
||||
3961 => ['MMMLMXI'],
|
||||
3962 => ['MMMLMXII'],
|
||||
3963 => ['MMMLMXIII'],
|
||||
3964 => ['MMMLMXIV'],
|
||||
3965 => ['MMMLMXV'],
|
||||
3966 => ['MMMLMXVI'],
|
||||
3967 => ['MMMLMXVII'],
|
||||
3968 => ['MMMLMXVIII'],
|
||||
3969 => ['MMMLMXIX'],
|
||||
3970 => ['MMMLMXX'],
|
||||
3971 => ['MMMLMXXI'],
|
||||
3972 => ['MMMLMXXII'],
|
||||
3973 => ['MMMLMXXIII'],
|
||||
3974 => ['MMMLMXXIV'],
|
||||
3975 => ['MMMLMXXV'],
|
||||
3976 => ['MMMLMXXVI'],
|
||||
3977 => ['MMMLMXXVII'],
|
||||
3978 => ['MMMLMXXVIII'],
|
||||
3979 => ['MMMLMXXIX'],
|
||||
3980 => ['MMMLMXXX'],
|
||||
3981 => ['MMMLMXXXI'],
|
||||
3982 => ['MMMLMXXXII'],
|
||||
3983 => ['MMMLMXXXIII'],
|
||||
3984 => ['MMMLMXXXIV'],
|
||||
3985 => ['MMMLMXXXV'],
|
||||
3986 => ['MMMLMXXXVI'],
|
||||
3987 => ['MMMLMXXXVII'],
|
||||
3988 => ['MMMLMXXXVIII'],
|
||||
3989 => ['MMMLMXXXIX'],
|
||||
3990 => ['MMMLMXL', 'MMMXM'],
|
||||
3991 => ['MMMLMXLI', 'MMMXMI'],
|
||||
3992 => ['MMMLMXLII', 'MMMXMII'],
|
||||
3993 => ['MMMLMXLIII', 'MMMXMIII'],
|
||||
3994 => ['MMMLMXLIV', 'MMMXMIV'],
|
||||
3995 => ['MMMLMVL', 'MMMXMV', 'MMMVM'],
|
||||
3996 => ['MMMLMVLI', 'MMMXMVI', 'MMMVMI'],
|
||||
3997 => ['MMMLMVLII', 'MMMXMVII', 'MMMVMII'],
|
||||
3998 => ['MMMLMVLIII', 'MMMXMVIII', 'MMMVMIII'],
|
||||
3999 => ['MMMLMVLIV', 'MMMXMIX', 'MMMVMIV', 'MMMIM'],
|
||||
];
|
||||
|
||||
private const THOUSANDS = ['', 'M', 'MM', 'MMM'];
|
||||
private const HUNDREDS = ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'];
|
||||
private const TENS = ['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'];
|
||||
private const ONES = ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'];
|
||||
const MAX_ROMAN_VALUE = 3999;
|
||||
const MAX_ROMAN_STYLE = 4;
|
||||
|
||||
private static function valueOk(int $aValue, int $style): string
|
||||
{
|
||||
$origValue = $aValue;
|
||||
$m = \intdiv($aValue, 1000);
|
||||
$aValue %= 1000;
|
||||
$c = \intdiv($aValue, 100);
|
||||
$aValue %= 100;
|
||||
$t = \intdiv($aValue, 10);
|
||||
$aValue %= 10;
|
||||
$result = self::THOUSANDS[$m] . self::HUNDREDS[$c] . self::TENS[$t] . self::ONES[$aValue];
|
||||
if ($style > 0) {
|
||||
if (array_key_exists($origValue, self::VALUES)) {
|
||||
$arr = self::VALUES[$origValue];
|
||||
$idx = min($style, count($arr)) - 1;
|
||||
$result = $arr[$idx];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function styleOk(int $aValue, int $style): string
|
||||
{
|
||||
return ($aValue < 0 || $aValue > self::MAX_ROMAN_VALUE) ? ExcelError::VALUE() : self::valueOk($aValue, $style);
|
||||
}
|
||||
|
||||
public static function calculateRoman(int $aValue, int $style): string
|
||||
{
|
||||
return ($style < 0 || $style > self::MAX_ROMAN_STYLE) ? ExcelError::VALUE() : self::styleOk($aValue, $style);
|
||||
}
|
||||
|
||||
/**
|
||||
* ROMAN.
|
||||
*
|
||||
* Converts a number to Roman numeral
|
||||
*
|
||||
* @param mixed $aValue Number to convert
|
||||
* Or can be an array of numbers
|
||||
* @param mixed $style Number indicating one of five possible forms
|
||||
* Or can be an array of styles
|
||||
*
|
||||
* @return array|string Roman numeral, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function evaluate(mixed $aValue, mixed $style = 0): array|string
|
||||
{
|
||||
if (is_array($aValue) || is_array($style)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $aValue, $style);
|
||||
}
|
||||
|
||||
try {
|
||||
$aValue = Helpers::validateNumericNullBool($aValue);
|
||||
if (is_bool($style)) {
|
||||
$style = $style ? 0 : 4;
|
||||
}
|
||||
$style = Helpers::validateNumericNullSubstitution($style, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return self::calculateRoman((int) $aValue, (int) $style);
|
||||
}
|
||||
}
|
||||
218
lib/PhpSpreadsheet/Calculation/MathTrig/Round.php
Normal file
218
lib/PhpSpreadsheet/Calculation/MathTrig/Round.php
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Round
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* ROUND.
|
||||
*
|
||||
* Returns the result of builtin function round after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric, or can be an array of numbers
|
||||
* @param mixed $precision Should be int, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Rounded number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function round(mixed $number, mixed $precision): array|string|float
|
||||
{
|
||||
if (is_array($number) || is_array($precision)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $precision);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$precision = Helpers::validateNumericNullBool($precision);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return round($number, (int) $precision);
|
||||
}
|
||||
|
||||
/**
|
||||
* ROUNDUP.
|
||||
*
|
||||
* Rounds a number up to a specified number of decimal places
|
||||
*
|
||||
* @param array|float $number Number to round, or can be an array of numbers
|
||||
* @param array|int $digits Number of digits to which you want to round $number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function up($number, $digits): array|string|float
|
||||
{
|
||||
if (is_array($number) || is_array($digits)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $digits);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$digits = (int) Helpers::validateNumericNullSubstitution($digits, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* ROUNDDOWN.
|
||||
*
|
||||
* Rounds a number down to a specified number of decimal places
|
||||
*
|
||||
* @param array|float $number Number to round, or can be an array of numbers
|
||||
* @param array|int $digits Number of digits to which you want to round $number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function down($number, $digits): array|string|float
|
||||
{
|
||||
if (is_array($number) || is_array($digits)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $digits);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
$digits = (int) Helpers::validateNumericNullSubstitution($digits, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* MROUND.
|
||||
*
|
||||
* Rounds a number to the nearest multiple of a specified value
|
||||
*
|
||||
* @param mixed $number Expect float. Number to round, or can be an array of numbers
|
||||
* @param mixed $multiple Expect int. Multiple to which you want to round, or can be an array of numbers.
|
||||
*
|
||||
* @return array|float|int|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function multiple(mixed $number, mixed $multiple): array|string|int|float
|
||||
{
|
||||
if (is_array($number) || is_array($multiple)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $multiple);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullSubstitution($number, 0);
|
||||
$multiple = Helpers::validateNumericNullSubstitution($multiple, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if ($number == 0 || $multiple == 0) {
|
||||
return 0;
|
||||
}
|
||||
if ((Helpers::returnSign($number)) == (Helpers::returnSign($multiple))) {
|
||||
$multiplier = 1 / $multiple;
|
||||
|
||||
return round($number * $multiplier) / $multiplier;
|
||||
}
|
||||
|
||||
return ExcelError::NAN();
|
||||
}
|
||||
|
||||
/**
|
||||
* EVEN.
|
||||
*
|
||||
* Returns number rounded up to the nearest even integer.
|
||||
* You can use this function for processing items that come in twos. For example,
|
||||
* a packing crate accepts rows of one or two items. The crate is full when
|
||||
* the number of items, rounded up to the nearest two, matches the crate's
|
||||
* capacity.
|
||||
*
|
||||
* Excel Function:
|
||||
* EVEN(number)
|
||||
*
|
||||
* @param array|float $number Number to round, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function even($number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::getEven($number);
|
||||
}
|
||||
|
||||
/**
|
||||
* ODD.
|
||||
*
|
||||
* Returns number rounded up to the nearest odd integer.
|
||||
*
|
||||
* @param array|float $number Number to round, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|int|string Rounded Number, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function odd($number): array|string|int|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$significance = Helpers::returnSign($number);
|
||||
if ($significance == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$result = ceil($number / $significance) * $significance;
|
||||
if ($result == Helpers::getEven($result)) {
|
||||
$result += $significance;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
53
lib/PhpSpreadsheet/Calculation/MathTrig/SeriesSum.php
Normal file
53
lib/PhpSpreadsheet/Calculation/MathTrig/SeriesSum.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class SeriesSum
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* SERIESSUM.
|
||||
*
|
||||
* Returns the sum of a power series
|
||||
*
|
||||
* @param mixed $x Input value
|
||||
* @param mixed $n Initial power
|
||||
* @param mixed $m Step
|
||||
* @param mixed[] $args An array of coefficients for the Data Series
|
||||
*
|
||||
* @return array|float|int|string The result, or a string containing an error
|
||||
*/
|
||||
public static function evaluate(mixed $x, mixed $n, mixed $m, ...$args): array|string|float|int
|
||||
{
|
||||
if (is_array($x) || is_array($n) || is_array($m)) {
|
||||
return self::evaluateArrayArgumentsSubset([self::class, __FUNCTION__], 3, $x, $n, $m, ...$args);
|
||||
}
|
||||
|
||||
try {
|
||||
$x = Helpers::validateNumericNullSubstitution($x, 0);
|
||||
$n = Helpers::validateNumericNullSubstitution($n, 0);
|
||||
$m = Helpers::validateNumericNullSubstitution($m, 0);
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$returnValue = 0;
|
||||
$i = 0;
|
||||
foreach ($aArgs as $argx) {
|
||||
if ($argx !== null) {
|
||||
$arg = Helpers::validateNumericNullSubstitution($argx, 0);
|
||||
$returnValue += $arg * $x ** ($n + ($m * $i));
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
}
|
||||
38
lib/PhpSpreadsheet/Calculation/MathTrig/Sign.php
Normal file
38
lib/PhpSpreadsheet/Calculation/MathTrig/Sign.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Sign
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* SIGN.
|
||||
*
|
||||
* Determines the sign of a number. Returns 1 if the number is positive, zero (0)
|
||||
* if the number is 0, and -1 if the number is negative.
|
||||
*
|
||||
* @param array|float $number Number to round, or can be an array of numbers
|
||||
*
|
||||
* @return array|int|string sign value, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function evaluate($number): array|string|int
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::returnSign($number);
|
||||
}
|
||||
}
|
||||
64
lib/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php
Normal file
64
lib/PhpSpreadsheet/Calculation/MathTrig/Sqrt.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Sqrt
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* SQRT.
|
||||
*
|
||||
* Returns the result of builtin function sqrt after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string square root
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function sqrt(mixed $number)
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::numberOrNan(sqrt($number));
|
||||
}
|
||||
|
||||
/**
|
||||
* SQRTPI.
|
||||
*
|
||||
* Returns the square root of (number * pi).
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string Square Root of Number * Pi, or a string containing an error
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function pi($number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullSubstitution($number, 0);
|
||||
Helpers::validateNotNegative($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return sqrt($number * M_PI);
|
||||
}
|
||||
}
|
||||
127
lib/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
Normal file
127
lib/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
class Subtotal
|
||||
{
|
||||
protected static function filterHiddenArgs(mixed $cellReference, mixed $args): array
|
||||
{
|
||||
return array_filter(
|
||||
$args,
|
||||
function ($index) use ($cellReference) {
|
||||
$explodeArray = explode('.', $index);
|
||||
$row = $explodeArray[1] ?? '';
|
||||
if (!is_numeric($row)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $cellReference->getWorksheet()->getRowDimension($row)->getVisible();
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
|
||||
protected static function filterFormulaArgs(mixed $cellReference, mixed $args): array
|
||||
{
|
||||
return array_filter(
|
||||
$args,
|
||||
function ($index) use ($cellReference): bool {
|
||||
$explodeArray = explode('.', $index);
|
||||
$row = $explodeArray[1] ?? '';
|
||||
$column = $explodeArray[2] ?? '';
|
||||
$retVal = true;
|
||||
if ($cellReference->getWorksheet()->cellExists($column . $row)) {
|
||||
//take this cell out if it contains the SUBTOTAL or AGGREGATE functions in a formula
|
||||
$isFormula = $cellReference->getWorksheet()->getCell($column . $row)->isFormula();
|
||||
$cellFormula = !preg_match(
|
||||
'/^=.*\b(SUBTOTAL|AGGREGATE)\s*\(/i',
|
||||
$cellReference->getWorksheet()->getCell($column . $row)->getValue() ?? ''
|
||||
);
|
||||
|
||||
$retVal = !$isFormula || $cellFormula;
|
||||
}
|
||||
|
||||
return $retVal;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array<int, callable>
|
||||
*/
|
||||
private const CALL_FUNCTIONS = [
|
||||
1 => [Statistical\Averages::class, 'average'], // 1 and 101
|
||||
[Statistical\Counts::class, 'COUNT'], // 2 and 102
|
||||
[Statistical\Counts::class, 'COUNTA'], // 3 and 103
|
||||
[Statistical\Maximum::class, 'max'], // 4 and 104
|
||||
[Statistical\Minimum::class, 'min'], // 5 and 105
|
||||
[Operations::class, 'product'], // 6 and 106
|
||||
[Statistical\StandardDeviations::class, 'STDEV'], // 7 and 107
|
||||
[Statistical\StandardDeviations::class, 'STDEVP'], // 8 and 108
|
||||
[Sum::class, 'sumIgnoringStrings'], // 9 and 109
|
||||
[Statistical\Variances::class, 'VAR'], // 10 and 110
|
||||
[Statistical\Variances::class, 'VARP'], // 111 and 111
|
||||
];
|
||||
|
||||
/**
|
||||
* SUBTOTAL.
|
||||
*
|
||||
* Returns a subtotal in a list or database.
|
||||
*
|
||||
* @param mixed $functionType
|
||||
* A number 1 to 11 that specifies which function to
|
||||
* use in calculating subtotals within a range
|
||||
* list
|
||||
* Numbers 101 to 111 shadow the functions of 1 to 11
|
||||
* but ignore any values in the range that are
|
||||
* in hidden rows
|
||||
* @param mixed[] $args A mixed data series of values
|
||||
*/
|
||||
public static function evaluate(mixed $functionType, ...$args): float|int|string
|
||||
{
|
||||
$cellReference = array_pop($args);
|
||||
$bArgs = Functions::flattenArrayIndexed($args);
|
||||
$aArgs = [];
|
||||
// int keys must come before string keys for PHP 8.0+
|
||||
// Otherwise, PHP thinks positional args follow keyword
|
||||
// in the subsequent call to call_user_func_array.
|
||||
// Fortunately, order of args is unimportant to Subtotal.
|
||||
foreach ($bArgs as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
$aArgs[$key] = $value;
|
||||
}
|
||||
}
|
||||
foreach ($bArgs as $key => $value) {
|
||||
if (!is_int($key)) {
|
||||
$aArgs[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$subtotal = (int) Helpers::validateNumericNullBool($functionType);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
// Calculate
|
||||
if ($subtotal > 100) {
|
||||
$aArgs = self::filterHiddenArgs($cellReference, $aArgs);
|
||||
$subtotal -= 100;
|
||||
}
|
||||
|
||||
$aArgs = self::filterFormulaArgs($cellReference, $aArgs);
|
||||
if (array_key_exists($subtotal, self::CALL_FUNCTIONS)) {
|
||||
$call = self::CALL_FUNCTIONS[$subtotal];
|
||||
|
||||
return call_user_func_array($call, $aArgs);
|
||||
}
|
||||
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
}
|
||||
110
lib/PhpSpreadsheet/Calculation/MathTrig/Sum.php
Normal file
110
lib/PhpSpreadsheet/Calculation/MathTrig/Sum.php
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Sum
|
||||
{
|
||||
/**
|
||||
* SUM, ignoring non-numeric non-error strings. This is eventually used by SUMIF.
|
||||
*
|
||||
* SUM computes the sum of all the values and cells referenced in the argument list.
|
||||
*
|
||||
* Excel Function:
|
||||
* SUM(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*/
|
||||
public static function sumIgnoringStrings(mixed ...$args): float|int|string
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through the arguments
|
||||
foreach (Functions::flattenArray($args) as $arg) {
|
||||
// Is it a numeric value?
|
||||
if (is_numeric($arg)) {
|
||||
$returnValue += $arg;
|
||||
} elseif (ErrorValue::isError($arg)) {
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* SUM, returning error for non-numeric strings. This is used by Excel SUM function.
|
||||
*
|
||||
* SUM computes the sum of all the values and cells referenced in the argument list.
|
||||
*
|
||||
* Excel Function:
|
||||
* SUM(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*/
|
||||
public static function sumErroringStrings(mixed ...$args): float|int|string|array
|
||||
{
|
||||
$returnValue = 0;
|
||||
// Loop through the arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
// Is it a numeric value?
|
||||
if (is_numeric($arg)) {
|
||||
$returnValue += $arg;
|
||||
} elseif (is_bool($arg)) {
|
||||
$returnValue += (int) $arg;
|
||||
} elseif (ErrorValue::isError($arg)) {
|
||||
return $arg;
|
||||
} elseif ($arg !== null && !Functions::isCellValue($k)) {
|
||||
// ignore non-numerics from cell, but fail as literals (except null)
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* SUMPRODUCT.
|
||||
*
|
||||
* Excel Function:
|
||||
* SUMPRODUCT(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|int|string The result, or a string containing an error
|
||||
*/
|
||||
public static function product(mixed ...$args): string|int|float
|
||||
{
|
||||
$arrayList = $args;
|
||||
|
||||
$wrkArray = Functions::flattenArray(array_shift($arrayList));
|
||||
$wrkCellCount = count($wrkArray);
|
||||
|
||||
for ($i = 0; $i < $wrkCellCount; ++$i) {
|
||||
if ((!is_numeric($wrkArray[$i])) || (is_string($wrkArray[$i]))) {
|
||||
$wrkArray[$i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($arrayList as $matrixData) {
|
||||
$array2 = Functions::flattenArray($matrixData);
|
||||
$count = count($array2);
|
||||
if ($wrkCellCount != $count) {
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
|
||||
foreach ($array2 as $i => $val) {
|
||||
if ((!is_numeric($val)) || (is_string($val))) {
|
||||
$val = 0;
|
||||
}
|
||||
$wrkArray[$i] *= $val;
|
||||
}
|
||||
}
|
||||
|
||||
return array_sum($wrkArray);
|
||||
}
|
||||
}
|
||||
133
lib/PhpSpreadsheet/Calculation/MathTrig/SumSquares.php
Normal file
133
lib/PhpSpreadsheet/Calculation/MathTrig/SumSquares.php
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class SumSquares
|
||||
{
|
||||
/**
|
||||
* SUMSQ.
|
||||
*
|
||||
* SUMSQ returns the sum of the squares of the arguments
|
||||
*
|
||||
* Excel Function:
|
||||
* SUMSQ(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*/
|
||||
public static function sumSquare(mixed ...$args): string|int|float
|
||||
{
|
||||
try {
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through arguments
|
||||
foreach (Functions::flattenArray($args) as $arg) {
|
||||
$arg1 = Helpers::validateNumericNullSubstitution($arg, 0);
|
||||
$returnValue += ($arg1 * $arg1);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
private static function getCount(array $array1, array $array2): int
|
||||
{
|
||||
$count = count($array1);
|
||||
if ($count !== count($array2)) {
|
||||
throw new Exception(ExcelError::NA());
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* These functions accept only numeric arguments, not even strings which are numeric.
|
||||
*/
|
||||
private static function numericNotString(mixed $item): bool
|
||||
{
|
||||
return is_numeric($item) && !is_string($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* SUMX2MY2.
|
||||
*
|
||||
* @param mixed[] $matrixData1 Matrix #1
|
||||
* @param mixed[] $matrixData2 Matrix #2
|
||||
*/
|
||||
public static function sumXSquaredMinusYSquared(array $matrixData1, array $matrixData2): string|int|float
|
||||
{
|
||||
try {
|
||||
$array1 = Functions::flattenArray($matrixData1);
|
||||
$array2 = Functions::flattenArray($matrixData2);
|
||||
$count = self::getCount($array1, $array2);
|
||||
|
||||
$result = 0;
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
if (self::numericNotString($array1[$i]) && self::numericNotString($array2[$i])) {
|
||||
$result += ($array1[$i] * $array1[$i]) - ($array2[$i] * $array2[$i]);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* SUMX2PY2.
|
||||
*
|
||||
* @param mixed[] $matrixData1 Matrix #1
|
||||
* @param mixed[] $matrixData2 Matrix #2
|
||||
*/
|
||||
public static function sumXSquaredPlusYSquared(array $matrixData1, array $matrixData2): string|int|float
|
||||
{
|
||||
try {
|
||||
$array1 = Functions::flattenArray($matrixData1);
|
||||
$array2 = Functions::flattenArray($matrixData2);
|
||||
$count = self::getCount($array1, $array2);
|
||||
|
||||
$result = 0;
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
if (self::numericNotString($array1[$i]) && self::numericNotString($array2[$i])) {
|
||||
$result += ($array1[$i] * $array1[$i]) + ($array2[$i] * $array2[$i]);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* SUMXMY2.
|
||||
*
|
||||
* @param mixed[] $matrixData1 Matrix #1
|
||||
* @param mixed[] $matrixData2 Matrix #2
|
||||
*/
|
||||
public static function sumXMinusYSquared(array $matrixData1, array $matrixData2): string|int|float
|
||||
{
|
||||
try {
|
||||
$array1 = Functions::flattenArray($matrixData1);
|
||||
$array2 = Functions::flattenArray($matrixData2);
|
||||
$count = self::getCount($array1, $array2);
|
||||
|
||||
$result = 0;
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
if (self::numericNotString($array1[$i]) && self::numericNotString($array2[$i])) {
|
||||
$result += ($array1[$i] - $array2[$i]) * ($array1[$i] - $array2[$i]);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
64
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php
Normal file
64
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosecant.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers;
|
||||
|
||||
class Cosecant
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* CSC.
|
||||
*
|
||||
* Returns the cosecant of an angle.
|
||||
*
|
||||
* @param array|float $angle Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The cosecant of the angle
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function csc($angle)
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::verySmallDenominator(1.0, sin($angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* CSCH.
|
||||
*
|
||||
* Returns the hyperbolic cosecant of an angle.
|
||||
*
|
||||
* @param array|float $angle Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The hyperbolic cosecant of the angle
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function csch($angle)
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::verySmallDenominator(1.0, sinh($angle));
|
||||
}
|
||||
}
|
||||
116
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php
Normal file
116
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Cosine.php
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers;
|
||||
|
||||
class Cosine
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* COS.
|
||||
*
|
||||
* Returns the result of builtin function cos after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string cosine
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function cos(mixed $number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return cos($number);
|
||||
}
|
||||
|
||||
/**
|
||||
* COSH.
|
||||
*
|
||||
* Returns the result of builtin function cosh after validating args.
|
||||
*
|
||||
* @param mixed $number Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string hyperbolic cosine
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function cosh(mixed $number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return cosh($number);
|
||||
}
|
||||
|
||||
/**
|
||||
* ACOS.
|
||||
*
|
||||
* Returns the arccosine of a number.
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The arccosine of the number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function acos($number)
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::numberOrNan(acos($number));
|
||||
}
|
||||
|
||||
/**
|
||||
* ACOSH.
|
||||
*
|
||||
* Returns the arc inverse hyperbolic cosine of a number.
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The inverse hyperbolic cosine of the number, or an error string
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function acosh($number)
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::numberOrNan(acosh($number));
|
||||
}
|
||||
}
|
||||
118
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php
Normal file
118
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Cotangent.php
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers;
|
||||
|
||||
class Cotangent
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* COT.
|
||||
*
|
||||
* Returns the cotangent of an angle.
|
||||
*
|
||||
* @param array|float $angle Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The cotangent of the angle
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function cot($angle)
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::verySmallDenominator(cos($angle), sin($angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* COTH.
|
||||
*
|
||||
* Returns the hyperbolic cotangent of an angle.
|
||||
*
|
||||
* @param array|float $angle Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The hyperbolic cotangent of the angle
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function coth($angle)
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::verySmallDenominator(1.0, tanh($angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* ACOT.
|
||||
*
|
||||
* Returns the arccotangent of a number.
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The arccotangent of the number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function acot($number): array|string|float
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return (M_PI / 2) - atan($number);
|
||||
}
|
||||
|
||||
/**
|
||||
* ACOTH.
|
||||
*
|
||||
* Returns the hyperbolic arccotangent of a number.
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The hyperbolic arccotangent of the number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function acoth($number)
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$result = ($number === 1) ? NAN : (log(($number + 1) / ($number - 1)) / 2);
|
||||
|
||||
return Helpers::numberOrNan($result);
|
||||
}
|
||||
}
|
||||
64
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php
Normal file
64
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Secant.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers;
|
||||
|
||||
class Secant
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* SEC.
|
||||
*
|
||||
* Returns the secant of an angle.
|
||||
*
|
||||
* @param array|float $angle Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The secant of the angle
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function sec($angle)
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::verySmallDenominator(1.0, cos($angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* SECH.
|
||||
*
|
||||
* Returns the hyperbolic secant of an angle.
|
||||
*
|
||||
* @param array|float $angle Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The hyperbolic secant of the angle
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function sech($angle)
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::verySmallDenominator(1.0, cosh($angle));
|
||||
}
|
||||
}
|
||||
116
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php
Normal file
116
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Sine.php
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers;
|
||||
|
||||
class Sine
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* SIN.
|
||||
*
|
||||
* Returns the result of builtin function sin after validating args.
|
||||
*
|
||||
* @param mixed $angle Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string sine
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function sin(mixed $angle): array|string|float
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return sin($angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* SINH.
|
||||
*
|
||||
* Returns the result of builtin function sinh after validating args.
|
||||
*
|
||||
* @param mixed $angle Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string hyperbolic sine
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function sinh(mixed $angle): array|string|float
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return sinh($angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* ASIN.
|
||||
*
|
||||
* Returns the arcsine of a number.
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The arcsine of the number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function asin($number)
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::numberOrNan(asin($number));
|
||||
}
|
||||
|
||||
/**
|
||||
* ASINH.
|
||||
*
|
||||
* Returns the inverse hyperbolic sine of a number.
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The inverse hyperbolic sine of the number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function asinh($number)
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::numberOrNan(asinh($number));
|
||||
}
|
||||
}
|
||||
160
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php
Normal file
160
lib/PhpSpreadsheet/Calculation/MathTrig/Trig/Tangent.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers;
|
||||
|
||||
class Tangent
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* TAN.
|
||||
*
|
||||
* Returns the result of builtin function tan after validating args.
|
||||
*
|
||||
* @param mixed $angle Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string tangent
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function tan(mixed $angle)
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::verySmallDenominator(sin($angle), cos($angle));
|
||||
}
|
||||
|
||||
/**
|
||||
* TANH.
|
||||
*
|
||||
* Returns the result of builtin function sinh after validating args.
|
||||
*
|
||||
* @param mixed $angle Should be numeric, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string hyperbolic tangent
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function tanh(mixed $angle): array|string|float
|
||||
{
|
||||
if (is_array($angle)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $angle);
|
||||
}
|
||||
|
||||
try {
|
||||
$angle = Helpers::validateNumericNullBool($angle);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return tanh($angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* ATAN.
|
||||
*
|
||||
* Returns the arctangent of a number.
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The arctangent of the number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function atan($number)
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::numberOrNan(atan($number));
|
||||
}
|
||||
|
||||
/**
|
||||
* ATANH.
|
||||
*
|
||||
* Returns the inverse hyperbolic tangent of a number.
|
||||
*
|
||||
* @param array|float $number Number, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The inverse hyperbolic tangent of the number
|
||||
* If an array of numbers is passed as the argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function atanh($number)
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
try {
|
||||
$number = Helpers::validateNumericNullBool($number);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return Helpers::numberOrNan(atanh($number));
|
||||
}
|
||||
|
||||
/**
|
||||
* ATAN2.
|
||||
*
|
||||
* This function calculates the arc tangent of the two variables x and y. It is similar to
|
||||
* calculating the arc tangent of y ÷ x, except that the signs of both arguments are used
|
||||
* to determine the quadrant of the result.
|
||||
* The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a
|
||||
* point with coordinates (xCoordinate, yCoordinate). The angle is given in radians between
|
||||
* -pi and pi, excluding -pi.
|
||||
*
|
||||
* Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard
|
||||
* PHP atan2() function, so we need to reverse them here before calling the PHP atan() function.
|
||||
*
|
||||
* Excel Function:
|
||||
* ATAN2(xCoordinate,yCoordinate)
|
||||
*
|
||||
* @param mixed $xCoordinate should be float, the x-coordinate of the point, or can be an array of numbers
|
||||
* @param mixed $yCoordinate should be float, the y-coordinate of the point, or can be an array of numbers
|
||||
*
|
||||
* @return array|float|string The inverse tangent of the specified x- and y-coordinates, or a string containing an error
|
||||
* If an array of numbers is passed as one of the arguments, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function atan2(mixed $xCoordinate, mixed $yCoordinate): array|string|float
|
||||
{
|
||||
if (is_array($xCoordinate) || is_array($yCoordinate)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $xCoordinate, $yCoordinate);
|
||||
}
|
||||
|
||||
try {
|
||||
$xCoordinate = Helpers::validateNumericNullBool($xCoordinate);
|
||||
$yCoordinate = Helpers::validateNumericNullBool($yCoordinate);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
if (($xCoordinate == 0) && ($yCoordinate == 0)) {
|
||||
return ExcelError::DIV0();
|
||||
}
|
||||
|
||||
return atan2($yCoordinate, $xCoordinate);
|
||||
}
|
||||
}
|
||||
48
lib/PhpSpreadsheet/Calculation/MathTrig/Trunc.php
Normal file
48
lib/PhpSpreadsheet/Calculation/MathTrig/Trunc.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
|
||||
|
||||
class Trunc
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
/**
|
||||
* TRUNC.
|
||||
*
|
||||
* Truncates value to the number of fractional digits by number_digits.
|
||||
*
|
||||
* @param array|float $value Or can be an array of values
|
||||
* @param array|int $digits Or can be an array of values
|
||||
*
|
||||
* @return array|float|string Truncated value, or a string containing an error
|
||||
* If an array of numbers is passed as an argument, then the returned result will also be an array
|
||||
* with the same dimensions
|
||||
*/
|
||||
public static function evaluate(array|float|string|null $value = 0, array|int|string $digits = 0): array|float|string
|
||||
{
|
||||
if (is_array($value) || is_array($digits)) {
|
||||
return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $digits);
|
||||
}
|
||||
|
||||
try {
|
||||
$value = Helpers::validateNumericNullBool($value);
|
||||
$digits = Helpers::validateNumericNullSubstitution($digits, null);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
$digits = floor($digits);
|
||||
|
||||
// Truncate
|
||||
$adjust = 10 ** $digits;
|
||||
|
||||
if (($digits > 0) && (rtrim((string) (int) ((abs($value) - abs((int) $value)) * $adjust), '0') < $adjust / 10)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return ((int) ($value * $adjust)) / $adjust;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue