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

BC   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 355
Duplicated Lines 22.54 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 99.13%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 49
c 1
b 0
f 0
lcom 1
cbo 0
dl 80
loc 355
ccs 114
cts 115
cp 0.9913
rs 8.5454

25 Methods

Rating   Name   Duplication   Size   Complexity  
A setScale() 0 4 1
A ceil() 14 14 4
A checkIsFloat() 0 4 1
A checkIsFloatCleanZeros() 0 4 1
A isNegative() 0 4 1
A checkNumber() 0 8 3
A round() 0 14 3
A floor() 14 14 4
A abs() 0 10 2
A rand() 0 10 1
B max() 19 19 5
B min() 19 19 5
A roundDown() 7 7 2
A roundUp() 7 7 2
A getScale() 0 5 1
A add() 0 4 1
A comp() 0 4 1
A div() 0 7 2
A mod() 0 4 1
A fmod() 0 18 2
A mul() 0 7 2
A pow() 0 4 1
A powMod() 0 4 1
A sqrt() 0 4 1
A sub() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like BC often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BC, and based on these observations, apply Extract Interface, too.

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