-
Notifications
You must be signed in to change notification settings - Fork 0
/
fraction.cc
236 lines (202 loc) · 5.02 KB
/
fraction.cc
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#include <iostream>
#include <string>
#include <cstdlib>
#include "fraction.h"
using namespace std;
Fraction :: Fraction() {}
Fraction :: Fraction(long _num, long _den) {
this->num = _num;
this->den = _den;
}
Fraction :: Fraction(long _num) {
this->num = _num;
this->den = 1;
}
Fraction :: ~Fraction() {}
long Fraction :: get_num() const {
return this->num;
}
long Fraction :: get_den() const {
return this->den;
}
void Fraction :: set_num(long _num) {
this->num = _num;
}
void Fraction :: set_den(long _den) {
this->den = _den;
}
bool Fraction :: is_zero() const { //must be a valid form
return (this->den != 0 && this->num == 0);
}
bool Fraction :: undefined() const{
return (this->den == 0);
}
void Fraction :: read() {
string buf, buf_num, buf_den;
size_t found;
int i;
buf_num.clear();
buf_den.clear();
cin >> buf;
found = buf.find("/"); //string.npos stores the index at which the / has been found
//if it was found, a num/den format is expected
if(found != string :: npos) {
for(i = 0; i < found; i++)
buf_num.push_back(buf[i]);
for(i = found + 1; i < buf.length(); i++)
buf_den.push_back(buf[i]);
this->num = stoi(buf_num);
this->den = stoi(buf_den);
if(this->undefined()) {
cerr << "Invalid denumerator, setting fraction to " << this->num << endl;
this->den = 1;
}
}
else { //otherwise only the numerator is expected
for(i = 0; i < buf.length(); i++)
buf_num.push_back(buf[i]);
this->num = stoi(buf_num);
this->den = 1;
}
this->simplify();
}
string Fraction :: print() const {
string fraz;
fraz = to_string(this->num);
if(this->num < 10 && this->num >= 0)
fraz.insert(0, " ");
if(this->den != 1) {
fraz += "/" + to_string(this->den);
if(this->den < 10)
fraz += " ";
}
else fraz += " ";
return fraz;
}
double Fraction :: to_double() const {
return (double)num/(double)den;
}
Fraction Fraction :: reciprocal() const {
Fraction rec;
if(this->num == 0)
rec = *(this);
else rec = Fraction(this->den, this->num);
return rec;
}
//helper function for absolute value
static long my_abs(long n1) {
return ((n1 < 0) ? -n1 : n1);
}
//helper function for MCD used in simplification
static long mcd(long n1, long n2) {
long com;
bool found = false;
bool first = true; //first iteration
bool both_neg = (n1 < 0 && n2 < 0); //true if both negative
n1 = my_abs(n1);
n2 = my_abs(n2);
if(n2 > n1) { //Algorithm works for n1>=n2
int tmp = n1;
n1 = n2;
n2 = tmp;
}
com = n2;
while(!found && com > 1) {
if((n1 % com) == 0 && (n2 % com) == 0) {
found = true;
}
else {
if(first) {
com /= 2;
first = false;
}
else com--;
}
}
return ((both_neg)? -com : com);
}
void Fraction :: simplify() {
long com = mcd(this->den, this->num);
if(com > 1) { //the fraction can be simplified
this->num /= com;
this->den /= com;
}
if(den < 0) { //negative sign moved to numerator for convenience
this->num = -num;
this->den = -den;
}
if(is_zero())
den = 1;
}
// -- OPERATORS OVERRIDE ON FRACTIONS --
Fraction Fraction :: operator = (const Fraction& F) {
this->num = F.num;
this->den = F.den;
this->simplify();
return *this;
}
Fraction Fraction :: operator + (const Fraction& F) {
long nden = F.den * this->den;
long nnum = F.den * this->num + F.num * this->den;
Fraction res = Fraction(nnum, nden);
res.simplify();
return res;
}
Fraction Fraction :: operator - (const Fraction& F) {
long nden = F.den * this->den;
long nnum = F.den * this->num - F.num * this->den;
Fraction res = Fraction(nnum, nden);
res.simplify();
return res;
}
Fraction Fraction :: operator * (const Fraction& F) {
Fraction res = Fraction(this->num * F.num, this->den * F.den);
res.simplify();
return res;
}
Fraction Fraction :: operator / (const Fraction& F) {
return (*(this) * F.reciprocal());
}
bool Fraction :: operator == (const Fraction& F) {
return (this->num == F.num && this->den == F.den);
}
bool Fraction :: operator != (const Fraction& F) {
return (this->num != F.num || this->den != F.den);
}
// -- OPERATOR OVERRIDE ON FRACTIONS AND INTEGERS --
Fraction Fraction :: operator = (long n) {
this->num = n;
this->den = 1;
this->simplify();
return *(this);
}
Fraction Fraction :: operator + (long n) {
Fraction to_add = Fraction(n);
to_add = to_add + *(this);
to_add.simplify();
return to_add;
}
Fraction Fraction :: operator - (long n) {
Fraction to_sub = Fraction(n);
to_sub = *(this) - to_sub;
to_sub.simplify();
return to_sub;
}
Fraction Fraction :: operator * (long n) {
Fraction f = Fraction(this->num * n, this->den);
f.simplify();
return f;
}
Fraction Fraction :: operator / (long n) {
Fraction f = Fraction(this->num, this->den * n);
f.simplify();
return f;
}
bool Fraction :: operator == (long n) {
this->simplify();
return (this->num == n && this->den == 1);
}
bool Fraction :: operator != (long n) {
this->simplify();
return (this->num != n || this->den != 1);
}