Passed
Push — master ( 0c9ea3...d3f178 )
by kacper
01:52
created

BC::fmod()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2.004

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 18
ccs 9
cts 10
cp 0.9
rs 9.4285
cc 2
eloc 10
nc 2
nop 3
crap 2.004
1
<?php
2
3
namespace BCMathExtended;
4
5
/**
6
 * Class BC
7
 * @package BCMathExtended
8
 */
9
class BC
10
{
11
    const COMPARE_EQUAL = 0;
12
    const COMPARE_LEFT_GRATER = 1;
13
    const COMPARE_RIGHT_GRATER = -1;
14
15
    /**
16
     * @param int $scale
17
     */
18 2
    public static function setScale($scale)
19
    {
20 2
        bcscale($scale);
21 2
    }
22
23
    /**
24
     * @param int|string $number
25
     * @return string
26
     */
27 2 View Code Duplication
    public static function ceil($number)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
28
    {
29 2
        $number = (string)$number;
30
31 2
        if (self::checkIsFloat($number) && self::checkIsFloatCleanZeros($number)) {
32 2
            $result = 1;
33 2
            if (self::isNegative($number)) {
34 2
                --$result;
35
            }
36 2
            $number = self::add($number, $result, 0);
37
        }
38
39 2
        return self::checkNumber($number);
40
    }
41
42
    /**
43
     * @param int|string $number
44
     * @return bool
45
     */
46 6
    private static function checkIsFloat($number)
47
    {
48 6
        return false !== strpos($number, '.');
49
    }
50
51
    /**
52
     * @param int|string $number
53
     * @return bool
54
     */
55 5
    private static function checkIsFloatCleanZeros(&$number)
56
    {
57 5
        return false !== strpos($number = rtrim(rtrim($number, '0'), '.'), '.');
58
    }
59
60
    /**
61
     * @param $number
62
     * @return bool
63
     */
64 6
    private static function isNegative($number)
65
    {
66 6
        return 0 === strncmp('-', $number, 1);
67
    }
68
69
    /**
70
     * @param int|string $number
71
     * @return int|string
72
     */
73 7
    private static function checkNumber($number)
74
    {
75 7
        $number = str_replace('+', '', filter_var($number, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
76 7
        if ('-0' === $number || !is_numeric($number)) {
77 4
            return '0';
78
        }
79 7
        return $number;
80
    }
81
82
    /**
83
     * @param int|string $number
84
     * @param int $precision
85
     * @return string
86
     */
87 1
    public static function round($number, $precision = 0)
88
    {
89 1
        $number = (string)$number;
90
91 1
        if (self::checkIsFloat($number)) {
92 1
            if (self::isNegative($number)) {
93 1
                return self::sub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
94
            }
95
96 1
            return self::add($number, '0.' . str_repeat('0', $precision) . '5', $precision);
97
        }
98
99 1
        return self::checkNumber($number);
100
    }
101
102
    /**
103
     * @param int|string $number
104
     * @return string
105
     */
106 3 View Code Duplication
    public static function floor($number)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
107
    {
108 3
        $number = (string)$number;
109
110 3
        if (self::checkIsFloat($number) && self::checkIsFloatCleanZeros($number)) {
111 2
            $result = 0;
112 2
            if (self::isNegative($number)) {
113 2
                --$result;
114
            }
115 2
            $number = self::add($number, $result, 0);
116
        }
117
118 3
        return self::checkNumber($number);
119
    }
120
121
    /**
122
     * @param int|string $number
123
     * @return string
124
     */
125 1
    public static function abs($number)
126
    {
127 1
        $number = (string)$number;
128
129 1
        if (self::isNegative($number)) {
130 1
            $number = (string)substr($number, 1);
131
        }
132
133 1
        return self::checkNumber($number);
134
    }
135
136
    /**
137
     * @param int|string $min
138
     * @param int|string $max
139
     * @return string
140
     */
141 1
    public static function rand($min, $max)
142
    {
143 1
        $max = (string)$max;
144 1
        $min = (string)$min;
145
146 1
        $difference = self::add(self::sub($max, $min), 1);
147 1
        $randPercent = self::div(mt_rand(), mt_getrandmax(), 8);
148
149 1
        return self::add($min, self::mul($difference, $randPercent, 8), 0);
150
    }
151
152
    /**
153
     * @param array|int|string,...
154
     * @return null|int|string
155
     */
156 1 View Code Duplication
    public static function max()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
    {
158 1
        $max = null;
159 1
        $args = func_get_args();
160 1
        if (is_array($args[0])) {
161 1
            $args = $args[0];
162
        }
163 1
        foreach ($args as $value) {
164 1
            if (null === $max) {
165 1
                $max = $value;
166
            } else {
167 1
                if (self::comp($max, $value) < 0) {
168 1
                    $max = $value;
169
                }
170
            }
171
        }
172
173 1
        return $max;
174
    }
175
176
    /**
177
     * @param array|int|string,...
178
     * @return null|int|string
179
     */
180 1 View Code Duplication
    public static function min()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
    {
182 1
        $min = null;
183 1
        $args = func_get_args();
184 1
        if (is_array($args[0])) {
185 1
            $args = $args[0];
186
        }
187 1
        foreach ($args as $value) {
188 1
            if (null === $min) {
189 1
                $min = $value;
190
            } else {
191 1
                if (self::comp($min, $value) > 0) {
192 1
                    $min = $value;
193
                }
194
            }
195
        }
196
197 1
        return $min;
198
    }
199
200
    /**
201
     * @param int|string $number
202
     * @param int $precision
203
     * @return string
204
     */
205 1 View Code Duplication
    public static function roundDown($number, $precision = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
206
    {
207 1
        $multiply = self::pow(10, (string)abs($precision));
208 1
        return $precision < 0 ?
209 1
            self::mul(self::floor(self::div($number, $multiply)), $multiply, $precision) :
210 1
            self::div(self::floor(self::mul($number, $multiply)), $multiply, $precision);
211
    }
212
213
    /**
214
     * @param int|string $number
215
     * @param int $precision
216
     * @return string
217
     */
218 1 View Code Duplication
    public static function roundUp($number, $precision = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
219
    {
220 1
        $multiply = self::pow(10, (string)abs($precision));
221 1
        return $precision < 0 ?
222 1
            self::mul(self::ceil(self::div($number, $multiply)), $multiply, $precision) :
223 1
            self::div(self::ceil(self::mul($number, $multiply)), $multiply, $precision);
224
    }
225
226
    /**
227
     * @return int
228
     */
229 1
    public static function getScale()
230
    {
231 1
        $sqrt = bcsqrt('2');
232 1
        return strlen(substr($sqrt, strpos($sqrt, '.') + 1));
233
    }
234
235
    /**
236
     * @param string $leftOperand
237
     * @param string $rightOperand
238
     * @param int $scale
239
     * @return string
240
     */
241 7
    public static function add($leftOperand, $rightOperand, $scale = null)
242
    {
243 7
        return bcadd($leftOperand, $rightOperand, $scale);
244
    }
245
246
    /**
247
     * @param string $leftOperand
248
     * @param string $rightOperand
249
     * @param int $scale
250
     * @return int
251
     */
252 3
    public static function comp($leftOperand, $rightOperand, $scale = null)
253
    {
254 3
        return bccomp($leftOperand, $rightOperand, $scale);
255
    }
256
257
    /**
258
     * @param string $leftOperand
259
     * @param string $rightOperand
260
     * @param int $scale
261
     * @return string
262
     */
263 5
    public static function div($leftOperand, $rightOperand, $scale = null)
264
    {
265 5
        if (null === $scale) {
266 3
            return bcdiv($leftOperand, $rightOperand);
267
        }
268 5
        return bcdiv($leftOperand, $rightOperand, $scale);
269
    }
270
271
    /**
272
     * @param string $leftOperand
273
     * @param string $modulus
274
     * @return string
275
     */
276 1
    public static function mod($leftOperand, $modulus)
277
    {
278 1
        return bcmod($leftOperand, $modulus);
279
    }
280
281
    /**
282
     * @param string $leftOperand
283
     * @param string $modulus
284
     * @param int $scale
285
     * @return string
286
     */
287 1
    public static function fmod($leftOperand, $modulus, $scale = null)
288
    {
289
        // From PHP 7.2 on, bcmod can handle real numbers
290 1
        if (version_compare(PHP_VERSION, '7.2.0') >= 0) {
291
            return bcmod($leftOperand, $modulus);
292
        }
293
294
        // mod(a, b) = a - b * floor(a/b)
295 1
        return self::sub(
296 1
            $leftOperand,
297 1
            self::mul(
298 1
                $modulus,
299 1
                self::floor(self::div($leftOperand, $modulus, $scale)),
300 1
                $scale
301
            ),
302 1
            $scale
303
        );
304
    }
305
306
    /**
307
     * @param string $leftOperand
308
     * @param string $rightOperand
309
     * @param int $scale
310
     * @return string
311
     */
312 5
    public static function mul($leftOperand, $rightOperand, $scale = null)
313
    {
314 5
        if (null === $scale) {
315 3
            return bcmul($leftOperand, $rightOperand);
316
        }
317 5
        return bcmul($leftOperand, $rightOperand, $scale);
318
    }
319
320
    /**
321
     * @param string $leftOperand
322
     * @param string $rightOperand
323
     * @param int $scale
324
     * @return string
325
     */
326 3
    public static function pow($leftOperand, $rightOperand, $scale = null)
327
    {
328 3
        return bcpow($leftOperand, $rightOperand, $scale);
329
    }
330
331
    /**
332
     * @param string $leftOperand
333
     * @param string $rightOperand
334
     * @param string $modulus
335
     * @param int $scale
336
     * @return string
337
     */
338 1
    public static function powMod($leftOperand, $rightOperand, $modulus, $scale = null)
339
    {
340 1
        return bcpowmod($leftOperand, $rightOperand, $modulus, $scale);
341
    }
342
343
    /**
344
     * @param string $operand
345
     * @param int $scale
346
     * @return string
347
     */
348 1
    public static function sqrt($operand, $scale = null)
349
    {
350 1
        return bcsqrt($operand, $scale);
351
    }
352
353
    /**
354
     * @param string $leftOperand
355
     * @param string $rightOperand
356
     * @param int $scale
357
     * @return string
358
     */
359 4
    public static function sub($leftOperand, $rightOperand, $scale = null)
360
    {
361 4
        return bcsub($leftOperand, $rightOperand, $scale);
362
    }
363
}
364