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
 
10
class Ceiling
11
{
12
    use ArrayEnabled;
13
 
14
    /**
15
     * CEILING.
16
     *
17
     * Returns number rounded up, away from zero, to the nearest multiple of significance.
18
     *        For example, if you want to avoid using pennies in your prices and your product is
19
     *        priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the
20
     *        nearest nickel.
21
     *
22
     * Excel Function:
23
     *        CEILING(number[,significance])
24
     *
25
     * @param array|float $number the number you want the ceiling
26
     *                      Or can be an array of values
27
     * @param array|float $significance the multiple to which you want to round
28
     *                      Or can be an array of values
29
     *
30
     * @return array|float|string Rounded Number, or a string containing an error
31
     *         If an array of numbers is passed as an argument, then the returned result will also be an array
32
     *            with the same dimensions
33
     */
34
    public static function ceiling($number, $significance = null)
35
    {
36
        if (is_array($number) || is_array($significance)) {
37
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance);
38
        }
39
 
40
        if ($significance === null) {
41
            self::floorCheck1Arg();
42
        }
43
 
44
        try {
45
            $number = Helpers::validateNumericNullBool($number);
46
            $significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
47
        } catch (Exception $e) {
48
            return $e->getMessage();
49
        }
50
 
51
        return self::argumentsOk((float) $number, (float) $significance);
52
    }
53
 
54
    /**
55
     * CEILING.MATH.
56
     *
57
     * Round a number down to the nearest integer or to the nearest multiple of significance.
58
     *
59
     * Excel Function:
60
     *        CEILING.MATH(number[,significance[,mode]])
61
     *
62
     * @param mixed $number Number to round
63
     *                      Or can be an array of values
64
     * @param mixed $significance Significance
65
     *                      Or can be an array of values
66
     * @param array|int $mode direction to round negative numbers
67
     *                      Or can be an array of values
68
     *
69
     * @return array|float|string Rounded Number, or a string containing an error
70
     *         If an array of numbers is passed as an argument, then the returned result will also be an array
71
     *            with the same dimensions
72
     */
73
    public static function math(mixed $number, mixed $significance = null, $mode = 0): array|string|float
74
    {
75
        if (is_array($number) || is_array($significance) || is_array($mode)) {
76
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance, $mode);
77
        }
78
 
79
        try {
80
            $number = Helpers::validateNumericNullBool($number);
81
            $significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
82
            $mode = Helpers::validateNumericNullSubstitution($mode, null);
83
        } catch (Exception $e) {
84
            return $e->getMessage();
85
        }
86
 
87
        if (empty($significance * $number)) {
88
            return 0.0;
89
        }
90
        if (self::ceilingMathTest((float) $significance, (float) $number, (int) $mode)) {
91
            return floor($number / $significance) * $significance;
92
        }
93
 
94
        return ceil($number / $significance) * $significance;
95
    }
96
 
97
    /**
98
     * CEILING.PRECISE.
99
     *
100
     * Rounds number up, away from zero, to the nearest multiple of significance.
101
     *
102
     * Excel Function:
103
     *        CEILING.PRECISE(number[,significance])
104
     *
105
     * @param mixed $number the number you want to round
106
     *                      Or can be an array of values
107
     * @param array|float $significance the multiple to which you want to round
108
     *                      Or can be an array of values
109
     *
110
     * @return array|float|string Rounded Number, or a string containing an error
111
     *         If an array of numbers is passed as an argument, then the returned result will also be an array
112
     *            with the same dimensions
113
     */
114
    public static function precise(mixed $number, $significance = 1): array|string|float
115
    {
116
        if (is_array($number) || is_array($significance)) {
117
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $significance);
118
        }
119
 
120
        try {
121
            $number = Helpers::validateNumericNullBool($number);
122
            $significance = Helpers::validateNumericNullSubstitution($significance, null);
123
        } catch (Exception $e) {
124
            return $e->getMessage();
125
        }
126
 
127
        if (!$significance) {
128
            return 0.0;
129
        }
130
        $result = $number / abs($significance);
131
 
132
        return ceil($result) * $significance * (($significance < 0) ? -1 : 1);
133
    }
134
 
135
    /**
136
     * Let CEILINGMATH complexity pass Scrutinizer.
137
     */
138
    private static function ceilingMathTest(float $significance, float $number, int $mode): bool
139
    {
140
        return ($significance < 0) || ($number < 0 && !empty($mode));
141
    }
142
 
143
    /**
144
     * Avoid Scrutinizer problems concerning complexity.
145
     */
146
    private static function argumentsOk(float $number, float $significance): float|string
147
    {
148
        if (empty($number * $significance)) {
149
            return 0.0;
150
        }
151
        if (Helpers::returnSign($number) == Helpers::returnSign($significance)) {
152
            return ceil($number / $significance) * $significance;
153
        }
154
 
155
        return ExcelError::NAN();
156
    }
157
 
158
    private static function floorCheck1Arg(): void
159
    {
160
        $compatibility = Functions::getCompatibilityMode();
161
        if ($compatibility === Functions::COMPATIBILITY_EXCEL) {
162
            throw new Exception('Excel requires 2 arguments for CEILING');
163
        }
164
    }
165
}