Completed
Push — master ( 07bfe6...4767e4 )
by Derek Stephen
02:29 queued 01:09
created

Fraction::getFactors()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Del\Phi;
4
5
class Fraction
6
{
7
    /** @var int $whole */
8
    private $whole;
9
10
    /** @var int $numerator */
11
    private $numerator;
12
13
    /** @var int $denominator */
14
    private $denominator;
15
16
    /** @var bool $negative */
17
    private $negative;
18
19 4
    public function __construct($whole = 0, $numerator = 0, $denominator = 1)
20
    {
21 4
        $this->whole = $whole;
22 4
        $this->numerator = $numerator;
23 4
        $this->denominator = $denominator;
24 4
        $this->negative = false;
25 4
    }
26
27
    /**
28
     * @return int
29
     */
30 1
    public function getWhole()
31
    {
32 1
        return $this->whole;
33
    }
34
35
    /**
36
     * @param int $whole
37
     * @return Fraction
38
     */
39 4
    public function setWhole($whole)
40
    {
41 4
        $this->whole = $whole;
42 4
        return $this;
43
    }
44
45
    /**
46
     * @return int
47
     */
48 1
    public function getNumerator()
49
    {
50 1
        return $this->numerator;
51
    }
52
53
    /**
54
     * @param int $numerator
55
     * @return Fraction
56
     */
57 4
    public function setNumerator($numerator)
58
    {
59 4
        $this->numerator = $numerator;
60 4
        return $this;
61
    }
62
63
    /**
64
     * @return int
65
     */
66 1
    public function getDenominator()
67
    {
68 1
        return $this->denominator;
69
    }
70
71
    /**
72
     * @param int $denominator
73
     * @return Fraction
74
     */
75 4
    public function setDenominator($denominator)
76
    {
77 4
        $this->denominator = $denominator;
78 4
        return $this;
79
    }
80
81 1
    private function refactor()
82
    {
83
        // 9/8 would become 1 1/8 for instance
84 1
        if ($this->numerator >= $this->denominator && $this->denominator > 0) {
85 1
            $this->refactorWhole();
86
        }
87 1
        if ($this->numerator > 0 && $this->denominator > 0) {
88 1
            $this->refactorFraction();
89
        }
90 1
    }
91
92 1
    private function refactorWhole()
93
    {
94
        // decrement $x and the numerator by the denominator each loop, and add to the whole
95 1
        for ($x = $this->numerator; $x >= $this->denominator; $x = $x - $this->denominator) {
96 1
            $this->whole ++;
97 1
            $this->numerator -= $this->denominator;
98
        }
99 1
    }
100
101 1
    private function refactorFraction()
102
    {
103 1
        $gcd = $this->getGreatestCommonDenominator($this->numerator, $this->denominator);
104 1
        $this->numerator = $this->numerator / $gcd;
105 1
        $this->denominator = $this->denominator / $gcd;
106 1
    }
107
108
    /**
109
     * @param int $x
110
     * @param int $y
111
     * @return int
112
     */
113 1
    private function getGreatestCommonDenominator($x, $y)
114
    {
115
        // first get the common denominators of both numerator and denominator
116 1
        $factorsX = $this->getFactors($x);
117 1
        $factorsY = $this->getFactors($y);
118
119
        // common denominators will be in both arrays, so get the intersect
120 1
        $commonDenominators = array_intersect($factorsX, $factorsY);
121
122
        // greatest common denominator is the highest number (last in the array)
123 1
        $gcd = array_pop($commonDenominators);
124
125 1
        return $gcd;
126
    }
127
128
    /**
129
     * @param int $num
130
     * @return array The common denominators of $num
131
     */
132 1
    private function getFactors($num)
133
    {
134 1
        $factors = [];
135
        // get factors of the numerator
136 1
        for ($x = 1; $x <= $num; $x ++) {
137 1
            if ($num % $x == 0) {
138 1
                $factors[] = $x;
139
            }
140
        }
141 1
        return $factors;
142
    }
143
144
    /**
145
     * @return bool
146
     */
147
    public function isNegative()
148
    {
149
        return $this->negative;
150
    }
151
152
    /**
153
     * @param bool $negative
154
     * @return Fraction
155
     */
156
    public function setNegative($negative)
157
    {
158
        $this->negative = $negative;
159
        return $this;
160
    }
161
162
    /**
163
     * @return bool
164
     */
165 1
    public function isInteger()
166
    {
167 1
        return $this->numerator % $this->denominator == 0;
168
    }
169
170
    /**
171
     * @return string
172
     */
173 1
    public function __toString()
174
    {
175 1
        $this->refactor();
176
177
        // if the whole is 0, don't display it
178 1
        $whole = $this->whole == 0 ? '' : $this->whole;
179 1
        $fraction = $this->numerator > 0 ? $this->numerator.'/'.$this->denominator : '';
180 1
        $space = ($whole && $fraction) ? ' ' : '';
181
182 1
        return $whole.$space.$fraction;
183
    }
184
185
    /**
186
     * @return float
187
     */
188 1
    public function toDecimal()
189
    {
190
        /*
191
         * a divide symbol. so this is broken and will need refactoring to be accurate. ;-)
192
         */
193 1
        $decimal = $this->numerator / $this->denominator;
194 1
        $number =  $this->whole + $decimal;
195 1
        return $number;
196
    }
197
}