Completed
Push — master ( 461950...72be08 )
by Derek Stephen
01:10
created

Fraction::setWhole()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
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) {
85 1
            $this->refactorWhole();
86 1
        }
87 1
        if ($this->numerator > 0) {
88 1
            $this->refactorFraction();
89 1
        }
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 1
        }
99 1
    }
100
101
    /**
102
     * a/b × c/d = ac/bd
103
     */
104 1
    private function refactorFraction()
105
    {
106 1
        $gcd = $this->getGreatestCommonDenominator($this->numerator, $this->denominator);
107 1
        $this->numerator = $this->numerator / $gcd;
108 1
        $this->denominator = $this->denominator / $gcd;
109 1
    }
110
111
    /**
112
     * @param int $x
113
     * @param int $y
114
     * @return int
115
     */
116 1
    private function getGreatestCommonDenominator($x, $y)
117
    {
118
        // first get the common denominators of both numerator and denominator
119 1
        $factorsX = $this->getFactors($x);
120 1
        $factorsY = $this->getFactors($y);
121
122
        // common denominators will be in both arrays, so get the intersect
123 1
        $commonDenominators = array_intersect($factorsX, $factorsY);
124
125
        // greatest common denominator is the highest number (last in the array)
126 1
        $gcd = array_pop($commonDenominators);
127
        
128 1
        return $gcd;
129
    }
130
131
    /**
132
     * @param int $num
133
     * @return array The common denominators of $num
134
     */
135 1
    private function getFactors($num)
136
    {
137 1
        $factors = [];
138
        // get factors of the numerator
139 1
        for ($x = 1; $x <= $num; $x ++) {
140 1
            if ($num % $x == 0) {
141 1
                $factors[] = $x;
142 1
            }
143 1
        }
144 1
        return $factors;
145
    }
146
147
    /**
148
     * @return bool
149
     */
150
    public function isNegative()
151
    {
152
        return $this->negative;
153
    }
154
155
    /**
156
     * @param bool $negative
157
     * @return Fraction
158
     */
159
    public function setNegative($negative)
160
    {
161
        $this->negative = $negative;
162
        return $this;
163
    }
164
165
    /**
166
     * @return bool
167
     */
168 1
    public function isInteger()
169
    {
170 1
        return $this->numerator % $this->denominator == 0;
171
    }
172
173
    /**
174
     * @return string
175
     */
176 1
    public function __toString()
177
    {
178 1
        $this->refactor();
179
180
        // if the whole is 0, don't display it
181 1
        $whole = $this->whole == 0 ? '' : $this->whole;
182 1
        $fraction = $this->numerator > 0 ? $this->numerator.'/'.$this->denominator : '';
183 1
        $space = ($whole && $fraction) ? ' ' : '';
184
185 1
        return $whole.$space.$fraction;
186
    }
187
188
    /**
189
     * @return float
190
     */
191 1
    public function toDecimal()
192
    {
193
        /*
194
         * a divide symbol. so this is broken and will need refactoring to be accurate. ;-)
195
         */
196 1
        $decimal = $this->numerator / $this->denominator;
197 1
        $number =  $this->whole + $decimal;
198 1
        return $number;
199
    }
200
}