Passed
Pull Request — develop (#27)
by Glynn
04:14 queued 01:34
created

power()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 2
nop 1
dl 0
loc 16
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Number functions.
5
 *
6
 * This file is part of PinkCrab Function Constructors.
7
 *
8
 * PinkCrab Function Constructors is free software: you can redistribute it and/or modify it under the terms of the
9
 * GNU General Public License as published by the Free Software Foundation, either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * PinkCrab Function Constructors is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
13
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 * See the GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with PinkCrab Function Constructors.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 *
19
 * @author Glynn Quelch <[email protected]>
20
 * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
21
 * @package PinkCrab\FunctionConstructors
22
 * @since 0.0.1
23
 *
24
 * @template Number of int|float
25
 * @phpstan-template Number of int|float
26
 * @psalm-template Number of int|float
27
 */
28
29
declare(strict_types=1);
30
31
namespace PinkCrab\FunctionConstructors\Numbers;
32
33
use Closure;
34
use InvalidArgumentException;
35
use PinkCrab\FunctionConstructors\Comparisons as C;
1 ignored issue
show
Bug introduced by
The type PinkCrab\FunctionConstructors\Comparisons was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
36
37
/**
38
 * Used to accumulate integers
39
 *
40
 * @param int $initial
41
 * @return Closure(int|null):(Closure|int)
42
 */
43
function accumulatorInt(int $initial = 0): Closure
44
{
45
    /**
46
     * @param int|null $value
47
     * @return Closure(int|null):(Closure|int)|int
48
     */
49
    return function (?int $value = null) use ($initial) {
50
        if ($value) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $value of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
51
            $initial += $value;
52
        }
53
        return $value ? accumulatorInt($initial) : $initial;
54
    };
55
}
56
57
/**
58
 * Used to accumulate floats
59
 *
60
 * @param float $initial
61
 * @return Closure(float|null):(Closure|float)
62
 */
63
function accumulatorFloat(float $initial = 0): Closure
64
{
65
    /**
66
     * @param float|null $value
67
     * @return Closure(float|null):(Closure|float)|float
68
     */
69
    return function (?float $value = null) use ($initial) {
70
        if ($value) {
71
            $initial += $value;
72
        }
73
        return $value ? accumulatorFloat($initial) : $initial;
74
    };
75
}
76
77
/**
78
 * Returns a function for adding a fixed amount.
79
 *
80
 * @param Number $initial Defaults to 0
81
 * @return Closure(Number):Number
82
 * @throws InvalidArgumentException If neither int or float passed.
83
 */
84
function sum($initial = 0): Closure
85
{
86
    if (! C\isNumber($initial)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

86
    if (! /** @scrutinizer ignore-call */ C\isNumber($initial)) {
Loading history...
87
        throw new InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
88
    }
89
90
    /**
91
     * @param Number $value
92
     * @return int|float
93
     */
94
    return function ($value) use ($initial) {
95
        return $initial + $value;
96
    };
97
}
98
99
100
/**
101
 * Returns a function for adding a fixed amount.
102
 *
103
 * @param int $initial Defaults to 0
104
 * @return Closure(Number):Number
105
 * @throws InvalidArgumentException If neither int or float passed.
106
 */
107
function subtract($initial = 0): Closure
108
{
109
    if (! C\isNumber($initial)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

109
    if (! /** @scrutinizer ignore-call */ C\isNumber($initial)) {
Loading history...
110
        throw new InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
111
    }
112
113
    /**
114
     * @param Number $value
115
     * @return int|float
116
     */
117
    return function ($value) use ($initial) {
118
        return $value - $initial;
119
    };
120
}
121
122
123
/**
124
 * Returns a function for multiplying a fixed amount.
125
 *
126
 * @param Number $initial Defaults to 1
127
 * @return Closure(Number):Number
128
 * @throws InvalidArgumentException
129
 */
130
function multiply($initial = 1): Closure
131
{
132
    if (! C\isNumber($initial)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

132
    if (! /** @scrutinizer ignore-call */ C\isNumber($initial)) {
Loading history...
133
        throw new InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
134
    }
135
136
    /**
137
     * @param Number $value
138
     * @return Number
139
     */
140
    return function ($value) use ($initial) {
141
        return $value * $initial;
142
    };
143
}
144
145
146
147
/**
148
 * Returns a function for divideBy a fixed amount.
149
 *
150
 * @param float $divisor The value to divide the passed value by
151
 * @return Closure(Number):float
152
 * @throws InvalidArgumentException If neither int or float passed.
153
 */
154
function divideBy($divisor = 1): Closure
155
{
156
    if (! C\isNumber($divisor)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
    if (! /** @scrutinizer ignore-call */ C\isNumber($divisor)) {
Loading history...
157
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
158
    }
159
160
    /**
161
     * @param float $value
162
     * @return float
163
     */
164
    return function ($value) use ($divisor): float {
165
        return $value / $divisor;
166
    };
167
}
168
169
/**
170
 * Returns a function for divideInto a fixed amount.
171
 *
172
 * @param float $dividend The value to divide the passed value by
173
 * @return Closure(Number):float
174
 * @throws InvalidArgumentException If neither int or float passed.
175
 */
176
function divideInto($dividend = 1): Closure
177
{
178
    if (! C\isNumber($dividend)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

178
    if (! /** @scrutinizer ignore-call */ C\isNumber($dividend)) {
Loading history...
179
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
180
    }
181
182
    /**
183
     * @param float $value
184
     * @return float
185
     */
186
    return function ($value) use ($dividend): float {
187
        return $dividend / $value;
188
    };
189
}
190
191
/**
192
 * Returns a function for getting the remainder with a fixed divisor.
193
 *
194
 * @param float $divisor
195
 * @return Closure(Number):float
196
 * @throws InvalidArgumentException If neither int or float passed.
197
 */
198
function remainderBy($divisor = 1): Closure
199
{
200
    if (! C\isNumber($divisor)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

200
    if (! /** @scrutinizer ignore-call */ C\isNumber($divisor)) {
Loading history...
201
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
202
    }
203
204
    /**
205
     * @param float $value
206
     * @return float
207
     */
208
    return function ($value) use ($divisor): float {
209
        return $value % $divisor;
210
    };
211
}
212
213
/**
214
 * Returns a function for getting the remainder with a fixed dividend.
215
 *
216
 * @param float $dividend
217
 * @return Closure(Number):float
218
 * @throws InvalidArgumentException If neither int or float passed.
219
 */
220
function remainderInto($dividend = 1): Closure
221
{
222
    if (! C\isNumber($dividend)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

222
    if (! /** @scrutinizer ignore-call */ C\isNumber($dividend)) {
Loading history...
223
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
224
    }
225
226
    /**
227
     * @param float $value
228
     * @return float
229
     */
230
    return function ($value) use ($dividend): float {
231
        return $dividend % $value;
232
    };
233
}
234
235
/**
236
 * Returns a function for checking if a number has a factor of another number.
237
 *
238
 * @param Number $factor
239
 * @return Closure(Number):bool
240
 * @throws InvalidArgumentException If neither int or float passed.
241
 */
242
function isFactorOf($factor): Closure
243
{
244
    if (! C\isNumber($factor)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

244
    if (! /** @scrutinizer ignore-call */ C\isNumber($factor)) {
Loading history...
245
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
246
    }
247
248
    /**
249
     * @param Number $value
250
     * @return bool
251
     * @throws InvalidArgumentException If neither int or float passed.
252
     */
253
    return function ($value) use ($factor): bool {
254
        if (! C\isNumber($value)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

254
        if (! /** @scrutinizer ignore-call */ C\isNumber($value)) {
Loading history...
255
            throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
256
        }
257
258
        // Return false if 0
259
        if ($value === 0) {
260
            return false;
261
        }
262
263
        return $value % $factor === 0;
264
    };
265
}
266
267
268
/**
269
 * Returns a function for getting the remainder with a fixed dividend.
270
 *
271
 * @param int $precision Number of decimal places.
272
 * @return Closure(Number):float
273
 * @throws InvalidArgumentException If neither int or float passed.
274
 */
275
function round($precision = 1): Closure
276
{
277
    if (! C\isNumber($precision)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

277
    if (! /** @scrutinizer ignore-call */ C\isNumber($precision)) {
Loading history...
278
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int)');
279
    }
280
281
    /**
282
     * @param Number $value
283
     * @return float
284
     * @throws InvalidArgumentException If neither int or float passed.
285
     */
286
    return function ($value) use ($precision): float {
287
        if (! C\isNumber($value)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

287
        if (! /** @scrutinizer ignore-call */ C\isNumber($value)) {
Loading history...
288
            throw new \InvalidArgumentException("Num\\round() only accepts a valid Number ( Int|Float -> Float )");
289
        }
290
        return \round(\floatval($value), $precision);
291
    };
292
}
293
294
/**
295
 * Returns a closure for raising the power of the passed by value, by a pre defined exponent.
296
 *
297
 * @param Number $exponent
298
 * @return Closure(Number):Number
299
 * @throws InvalidArgumentException If neither int or float passed.
300
 */
301
function power($exponent): Closure
302
{
303
    if (! C\isNumber($exponent)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

303
    if (! /** @scrutinizer ignore-call */ C\isNumber($exponent)) {
Loading history...
304
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int) for the exponent');
305
    }
306
307
    /**
308
     * @param Number $value
309
     * @return Number
310
     * @throws InvalidArgumentException If neither int or float passed.
311
     */
312
    return function ($value) use ($exponent) {
313
        if (! C\isNumber($value)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

313
        if (! /** @scrutinizer ignore-call */ C\isNumber($value)) {
Loading history...
314
            throw new \InvalidArgumentException('Num\\power() only accepts a valid Number ( Int|Float )');
315
        }
316
        return \pow($value, $exponent);
317
    };
318
}
319
320
/**
321
 * Returns closure for getting the pre defined root of a passed value.
322
 *
323
 * @param Number $root
324
 * @return Closure(Number):Number
325
 * @throws InvalidArgumentException If neither int or float passed.
326
 */
327
function root($root): Closure
328
{
329
    if (! C\isNumber($root)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

329
    if (! /** @scrutinizer ignore-call */ C\isNumber($root)) {
Loading history...
330
        throw new \InvalidArgumentException(__FUNCTION__ . 'only accepts a Number (Float or Int) for the root');
331
    }
332
333
    /**
334
     * @param Number $value
335
     * @return Number
336
     * @throws InvalidArgumentException If neither int or float passed.
337
     */
338
    return function ($value) use ($root) {
339
        if (! C\isNumber($value)) {
1 ignored issue
show
Bug introduced by
The function isNumber was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

339
        if (! /** @scrutinizer ignore-call */ C\isNumber($value)) {
Loading history...
340
            throw new \InvalidArgumentException('Num\\root() only accepts a valid Number ( Int|Float )');
341
        }
342
        return pow($value, (1 / $root));
343
    };
344
}
345