-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfraction.cpp
221 lines (185 loc) · 4.23 KB
/
fraction.cpp
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
#include "fraction.h"
//PUBLIC
//CTORS
fraction::fraction()
{
num = 0;
denom = 1;
}
fraction::fraction(int n, int d)
{
setValue(n,d);
}
fraction::fraction(std::string fracString) { //TESTED
setValue(fracString);
}
fraction::~fraction()
{
num = denom = 0;
}
/*
* The copy constructor is fired whenever
* 1. You pass by value
* 2. You use a return statement that
* does not got back to a reference
*/
fraction::fraction(const fraction &frac)
{
num = frac.num;
denom = frac.denom;
}
fraction::fraction(const double &other)
{
DecimaltoFrac(other, num, denom);
reduce();
}
//OPERATOR FUNCTIONS (NOT FRIENDS)
/*
* The assignment operator needs to be
* returned by reference so that you can
* "chain" operators.
* e.g.
* x = y = z;
*/
fraction& fraction::operator=(const fraction &frac)
{
if(this != &frac)
{
num = frac.num;
denom = frac.denom;
}
return *this;
}
fraction& fraction::operator+=(const fraction &other)
{
*this = *this + other;
return *this;
}
fraction& fraction::operator-=(const fraction &other)
{
*this = *this - other;
return *this;
}
fraction& fraction::operator*=(const fraction &other)
{
*this = *this * other;
return *this;
}
fraction& fraction::operator/=(const fraction &other)
{
*this = *this / other;
return *this;
}
//PUBLIC FUNCTIONS
int fraction::getNum() //accessor function for numerator
{
return num;
}
int fraction::getDenom()//accessor function for denominator
{
return denom;
}
void fraction::setValue(int n, int d) //mutator function
{
num = n;
denom = d;
reduce();
}
void fraction::setValue(std::string fracString) { //TESTED
std::stringstream ss;
ss<<fracString;
ss>>*this;
}
void fraction::display()
{
std::cout<<" "<<num;
if(denom != 1)
std::cout<<"/"<<denom<<" ";
}
void fraction::getInput()
{
char junk;
std::cin>>num>>junk>>denom;
reduce();
}
void fraction::reduce()
{
bool neg = num < 0 || denom < 0,
both = num < 0 && denom < 0;
int divisor = gcd(abs(num), abs(denom));
num = abs(num) / divisor;
denom = abs(denom) / divisor;
if(!both) //Asking is both == false
if(neg)
num *= -1;
}
fraction fraction::reduceFraction() {
fraction temp(num, denom);
temp.reduce();
return temp;
}
double fraction::evaluate() //TESTED
{
return num*1./denom;
}
double fraction::pow(fraction base, fraction power) { //TESTED
return std::pow(base.evaluate(), power.evaluate());
}
bool fraction::isExactlyTheSame(fraction other) {
return (num == other.num && denom == other.denom);
}
//PRIVATE
//PRIVATE UTILITY FUNCTIONS
int fraction::gcd(int p, int q)
{
return !q ? p : gcd(q, p%q); //!q is the same as asking q == 0;
}
/*
* Remainder Theorem
*
* P = nQ + R;
*
* 36 = (1)(24) + 12 Question, is 12 == 0?
* 24 = (2)(12) + 0 If no, move Q into P, and R into Q and continue
* until R == 0;
* If R== 0, that means Q is the GCD of the original numbers provided
*
*/
bool fraction::allDecimalsTheSame(const std::string &fracPart)
{
if(fracPart.size()<3)
return false;
bool yes = true;
for(unsigned int i = 1; yes && i < fracPart.size(); ++i)
yes = (fracPart[0] == fracPart[i]);
return yes;
}
int fraction::makeDenom(int digits, bool same)
{
std::string result("1");
for(int i = 0; i < digits; ++i)
result += "0";
return std::stoi(result) - (int)same * 1;
//stoi: convert string to integer
}
void fraction::DecimaltoFrac(const double &other, int &num_arg, int &denom_arg) {
//TESTED, COULD IMPROVE
std::string wholePart, fractionPart;
std::stringstream ss;
ss<<other;
getline(ss,wholePart,'.'); //treat '.' as a delimination char
getline(ss,fractionPart, '\n');
int numDigits = fractionPart.size();
denom_arg = makeDenom(numDigits, allDecimalsTheSame(fractionPart));
if(fractionPart.empty())
num_arg = denom_arg * std::stoi(wholePart);
else
num_arg = denom_arg * std::stoi(wholePart) + std::stoi(fractionPart);
}
double fraction::makeDouble(int intPart, int deciPart) {
std::stringstream ssdouble;
ssdouble<<intPart<<'.'<<deciPart;
double temp;
ssdouble>>temp;
return temp;
}