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\Information\ExcelError;
8
// following added in Php8.4
9
use RoundingMode;
10
 
11
class Round
12
{
13
    use ArrayEnabled;
14
 
15
    /**
16
     * ROUND.
17
     *
18
     * Returns the result of builtin function round after validating args.
19
     *
20
     * @param mixed $number Should be numeric, or can be an array of numbers
21
     * @param mixed $precision Should be int, or can be an array of numbers
22
     *
23
     * @return array|float|string Rounded number
24
     *         If an array of numbers is passed as the argument, then the returned result will also be an array
25
     *            with the same dimensions
26
     */
27
    public static function round(mixed $number, mixed $precision): array|string|float
28
    {
29
        if (is_array($number) || is_array($precision)) {
30
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $precision);
31
        }
32
 
33
        try {
34
            $number = Helpers::validateNumericNullBool($number);
35
            $precision = Helpers::validateNumericNullBool($precision);
36
        } catch (Exception $e) {
37
            return $e->getMessage();
38
        }
39
 
40
        return round($number, (int) $precision);
41
    }
42
 
43
    /**
44
     * ROUNDUP.
45
     *
46
     * Rounds a number up to a specified number of decimal places
47
     *
48
     * @param array|float $number Number to round, or can be an array of numbers
49
     * @param array|int $digits Number of digits to which you want to round $number, or can be an array of numbers
50
     *
51
     * @return array|float|string Rounded Number, or a string containing an error
52
     *         If an array of numbers is passed as the argument, then the returned result will also be an array
53
     *            with the same dimensions
54
     */
55
    public static function up($number, $digits): array|string|float
56
    {
57
        if (is_array($number) || is_array($digits)) {
58
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $digits);
59
        }
60
 
61
        try {
62
            $number = Helpers::validateNumericNullBool($number);
63
            $digits = (int) Helpers::validateNumericNullSubstitution($digits, null);
64
        } catch (Exception $e) {
65
            return $e->getMessage();
66
        }
67
 
68
        if ($number == 0.0) {
69
            return 0.0;
70
        }
71
 
72
        if (PHP_VERSION_ID >= 80400) {
73
            return round(
74
                (float) (string) $number,
75
                $digits,
76
                RoundingMode::AwayFromZero //* @phpstan-ignore-line
77
            );
78
        }
79
 
80
        if ($number < 0.0) {
81
            return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN);
82
        }
83
 
84
        return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_DOWN);
85
    }
86
 
87
    /**
88
     * ROUNDDOWN.
89
     *
90
     * Rounds a number down to a specified number of decimal places
91
     *
92
     * @param null|array|float|string $number Number to round, or can be an array of numbers
93
     * @param array|float|int|string $digits Number of digits to which you want to round $number, or can be an array of numbers
94
     *
95
     * @return array|float|string Rounded Number, or a string containing an error
96
     *         If an array of numbers is passed as the argument, then the returned result will also be an array
97
     *            with the same dimensions
98
     */
99
    public static function down($number, $digits): array|string|float
100
    {
101
        if (is_array($number) || is_array($digits)) {
102
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $digits);
103
        }
104
 
105
        try {
106
            $number = Helpers::validateNumericNullBool($number);
107
            $digits = (int) Helpers::validateNumericNullSubstitution($digits, null);
108
        } catch (Exception $e) {
109
            return $e->getMessage();
110
        }
111
 
112
        if ($number == 0.0) {
113
            return 0.0;
114
        }
115
 
116
        if (PHP_VERSION_ID >= 80400) {
117
            return round(
118
                (float) (string) $number,
119
                $digits,
120
                RoundingMode::TowardsZero //* @phpstan-ignore-line
121
            );
122
        }
123
 
124
        if ($number < 0.0) {
125
            return round($number + 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP);
126
        }
127
 
128
        return round($number - 0.5 * 0.1 ** $digits, $digits, PHP_ROUND_HALF_UP);
129
    }
130
 
131
    /**
132
     * MROUND.
133
     *
134
     * Rounds a number to the nearest multiple of a specified value
135
     *
136
     * @param mixed $number Expect float. Number to round, or can be an array of numbers
137
     * @param mixed $multiple Expect int. Multiple to which you want to round, or can be an array of numbers.
138
     *
139
     * @return array|float|int|string Rounded Number, or a string containing an error
140
     *         If an array of numbers is passed as the argument, then the returned result will also be an array
141
     *            with the same dimensions
142
     */
143
    public static function multiple(mixed $number, mixed $multiple): array|string|int|float
144
    {
145
        if (is_array($number) || is_array($multiple)) {
146
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $multiple);
147
        }
148
 
149
        try {
150
            $number = Helpers::validateNumericNullSubstitution($number, 0);
151
            $multiple = Helpers::validateNumericNullSubstitution($multiple, null);
152
        } catch (Exception $e) {
153
            return $e->getMessage();
154
        }
155
 
156
        if ($number == 0 || $multiple == 0) {
157
            return 0;
158
        }
159
        if ((Helpers::returnSign($number)) == (Helpers::returnSign($multiple))) {
160
            $multiplier = 1 / $multiple;
161
 
162
            return round($number * $multiplier) / $multiplier;
163
        }
164
 
165
        return ExcelError::NAN();
166
    }
167
 
168
    /**
169
     * EVEN.
170
     *
171
     * Returns number rounded up to the nearest even integer.
172
     * You can use this function for processing items that come in twos. For example,
173
     *        a packing crate accepts rows of one or two items. The crate is full when
174
     *        the number of items, rounded up to the nearest two, matches the crate's
175
     *        capacity.
176
     *
177
     * Excel Function:
178
     *        EVEN(number)
179
     *
180
     * @param array|float $number Number to round, or can be an array of numbers
181
     *
182
     * @return array|float|string Rounded Number, or a string containing an error
183
     *         If an array of numbers is passed as the argument, then the returned result will also be an array
184
     *            with the same dimensions
185
     */
186
    public static function even($number): array|string|float
187
    {
188
        if (is_array($number)) {
189
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
190
        }
191
 
192
        try {
193
            $number = Helpers::validateNumericNullBool($number);
194
        } catch (Exception $e) {
195
            return $e->getMessage();
196
        }
197
 
198
        return Helpers::getEven($number);
199
    }
200
 
201
    /**
202
     * ODD.
203
     *
204
     * Returns number rounded up to the nearest odd integer.
205
     *
206
     * @param array|float $number Number to round, or can be an array of numbers
207
     *
208
     * @return array|float|int|string Rounded Number, or a string containing an error
209
     *         If an array of numbers is passed as the argument, then the returned result will also be an array
210
     *            with the same dimensions
211
     */
212
    public static function odd($number): array|string|int|float
213
    {
214
        if (is_array($number)) {
215
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
216
        }
217
 
218
        try {
219
            $number = Helpers::validateNumericNullBool($number);
220
        } catch (Exception $e) {
221
            return $e->getMessage();
222
        }
223
 
224
        $significance = Helpers::returnSign($number);
225
        if ($significance == 0) {
226
            return 1;
227
        }
228
 
229
        $result = ceil($number / $significance) * $significance;
230
        if ($result == Helpers::getEven($result)) {
231
            $result += $significance;
232
        }
233
 
234
        return $result;
235
    }
236
}