-
Notifications
You must be signed in to change notification settings - Fork 3
/
RationalType.php
146 lines (127 loc) · 2.96 KB
/
RationalType.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
/*
* Hard type support
* For when you absolutely want to know what you are getting
*
* Thanks to Florian Wolters for the inspiration
* @link http://github.com/FlorianWolters/PHP-Component-Number-Fraction
*
* @author Ashley Kitson <akitson@zf4.biz>
* @copyright Ashley Kitson, UK, 2012
* @licence GPL V3 or later : http://www.gnu.org/licenses/gpl.html
*/
namespace chippyash\Type\Number\Rational;
use chippyash\Type\Number\Rational\AbstractRationalType;
use chippyash\Type\Number\IntType;
use chippyash\Type\BoolType;
/**
* A rational number (i.e a fraction)
* This is the native PHP type. If you have GMP installed, consider using
* RationalGCDType
*
*/
class RationalType extends AbstractRationalType
{
/**
* numerator
* @var int
*/
protected $num;
/**
* denominator
* @var int
*/
protected $den;
/**
* Set values for rational
*
* @param \chippyash\Type\Number\IntType $num numerator
* @param \chippyash\Type\Number\IntType $den denominator
* @param \chippyash\Type\BoolType $reduce -optional: default = true
*
* @return \chippyash\Type\Number\Rational\RationalType Fluent Interface
*/
public function setFromTypes(IntType $num, IntType $den, BoolType $reduce = null)
{
$this->num = $num->get();
$this->den = $den->get();
if ($this->den < 0) {
//normalise the sign
$this->num *= -1;
$this->den *= -1;
}
if (empty($reduce) || $reduce->get()) {
$this->reduce();
}
return $this;
}
/**
* Get the numerator
* @return int
*/
public function numerator()
{
return $this->num;
}
/**
* Get the denominator
*
* @return int
*/
public function denominator()
{
return $this->den;
}
/**
* Get the basic value of the object type properly
* In this case, the type is a float
*
* @return float
*/
public function get()
{
return floatval($this->num / $this->den);
}
/**
* Magic method - convert to string
* Returns "<num>/<den>"
*
* @return string
*/
public function __toString()
{
return "{$this->num}/{$this->den}";
}
/**
* Negates the number
*
* @returns chippyash\Type\Number\Rational\RationalType Fluent Interface
*/
public function negate()
{
$this->num *= -1;
return $this;
}
/**
* Reduce this number to it's lowest form
*/
protected function reduce()
{
$gcd = $this->gcd($this->num, $this->den);
if ($gcd > 1) {
$this->num /= $gcd;
$this->den /= $gcd;
}
}
/**
* Return GCD of two numbers
*
* @param int $a
* @param int $b
* @return int
*/
private function gcd($a, $b)
{
return $b ? $this->gcd($b, $a % $b) : $a;
}
}