Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
4
 
5
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
6
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
7
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
8
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
9
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
10
 
11
class Factorial
12
{
13
    use ArrayEnabled;
14
 
15
    /**
16
     * FACT.
17
     *
18
     * Returns the factorial of a number.
19
     * The factorial of a number is equal to 1*2*3*...* number.
20
     *
21
     * Excel Function:
22
     *        FACT(factVal)
23
     *
24
     * @param array|float $factVal Factorial Value, or can be an array of numbers
25
     *
26
     * @return array|float|int|string Factorial, or a string containing an error
27
     *         If an array of numbers is passed as the argument, then the returned result will also be an array
28
     *            with the same dimensions
29
     */
30
    public static function fact($factVal): array|string|float|int
31
    {
32
        if (is_array($factVal)) {
33
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $factVal);
34
        }
35
 
36
        try {
37
            $factVal = Helpers::validateNumericNullBool($factVal);
38
            Helpers::validateNotNegative($factVal);
39
        } catch (Exception $e) {
40
            return $e->getMessage();
41
        }
42
 
43
        $factLoop = floor($factVal);
44
        if ($factVal > $factLoop) {
45
            if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) {
46
                return Statistical\Distributions\Gamma::gammaValue($factVal + 1);
47
            }
48
        }
49
 
50
        $factorial = 1;
51
        while ($factLoop > 1) {
52
            $factorial *= $factLoop--;
53
        }
54
 
55
        return $factorial;
56
    }
57
 
58
    /**
59
     * FACTDOUBLE.
60
     *
61
     * Returns the double factorial of a number.
62
     *
63
     * Excel Function:
64
     *        FACTDOUBLE(factVal)
65
     *
66
     * @param array|float $factVal Factorial Value, or can be an array of numbers
67
     *
68
     * @return array|float|int|string Double Factorial, or a string containing an error
69
     *         If an array of numbers is passed as the argument, then the returned result will also be an array
70
     *            with the same dimensions
71
     */
72
    public static function factDouble($factVal): array|string|float|int
73
    {
74
        if (is_array($factVal)) {
75
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $factVal);
76
        }
77
 
78
        try {
79
            $factVal = Helpers::validateNumericNullSubstitution($factVal, 0);
80
            Helpers::validateNotNegative($factVal);
81
        } catch (Exception $e) {
82
            return $e->getMessage();
83
        }
84
 
85
        $factLoop = floor($factVal);
86
        $factorial = 1;
87
        while ($factLoop > 1) {
88
            $factorial *= $factLoop;
89
            $factLoop -= 2;
90
        }
91
 
92
        return $factorial;
93
    }
94
 
95
    /**
96
     * MULTINOMIAL.
97
     *
98
     * Returns the ratio of the factorial of a sum of values to the product of factorials.
99
     *
100
     * @param mixed[] $args An array of mixed values for the Data Series
101
     *
102
     * @return float|int|string The result, or a string containing an error
103
     */
104
    public static function multinomial(...$args): string|int|float
105
    {
106
        $summer = 0;
107
        $divisor = 1;
108
 
109
        try {
110
            // Loop through arguments
111
            foreach (Functions::flattenArray($args) as $argx) {
112
                $arg = Helpers::validateNumericNullSubstitution($argx, null);
113
                Helpers::validateNotNegative($arg);
114
                $arg = (int) $arg;
115
                $summer += $arg;
116
                $divisor *= self::fact($arg);
117
            }
118
        } catch (Exception $e) {
119
            return $e->getMessage();
120
        }
121
 
122
        $summer = self::fact($summer);
123
 
124
        return is_numeric($summer) ? ($summer / $divisor) : ExcelError::VALUE();
125
    }
126
}