-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathFraction.cpp
More file actions
107 lines (92 loc) · 2.4 KB
/
Copy pathFraction.cpp
File metadata and controls
107 lines (92 loc) · 2.4 KB
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
#include "Fraction.h"
#include <cmath>
#include "FractionParser.h"
Fraction::Fraction(FractionInt top, FractionInt bottom) {
this->top = top;
this->bottom = bottom;
this->reduce();
}
Fraction::Fraction(const std::string& fraction_string) {
Fraction fraction = FractionParser::stringToFraction(fraction_string);
this->top = fraction.getTop();
this->bottom = fraction.getBottom();
}
FractionInt Fraction::getTop() const { return this->top; }
FractionInt Fraction::getBottom() const { return this->bottom; }
// Make sure we reduce the fraction
// every time we change its values
void Fraction::setTop(FractionInt top) {
this->top = top;
this->reduce();
}
void Fraction::setBottom(FractionInt bottom) {
this->bottom = bottom;
this->reduce();
}
void Fraction::reduce() {
// Make sure only numerator has negative
if (this->bottom < 0) {
this->bottom = -this->bottom;
this->top = -this->top;
}
// Fraction is basic
// Basic bitches go home early
if (this->bottom == 1) {
return;
}
// Fix "zero" & "infinity" issues
if (this->bottom == 0) {
// Convert fraction to the standard infinity(1/0 or -1/0) or 0/0
this->top = (this->top == 0) ? 0 : (this->top > 0) ? 1 : -1;
return;
}
if (this->top == 0) {
// Convert fraction to the standard zero(0/1)
this->bottom = 1;
return;
}
// Reduce the fraction something something greatest
// common denominator something something algorithm
//
// It's a good thing I took discrete math
FractionInt gcd;
FractionInt a;
FractionInt b;
do {
a = this->top;
b = this->bottom;
gcd = a % b;
while (gcd != 0) {
a = b;
b = gcd;
gcd = a % b;
}
this->top /= b;
this->bottom /= b;
} while (1 != b);
}
bool Fraction::operator==(const Fraction& rhs) const {
return (this->top == rhs.top) && (this->bottom == rhs.bottom);
}
Fraction& Fraction::operator=(const Fraction& rhs) {
this->top = rhs.top;
this->bottom = rhs.bottom;
// Other fraction should already be reduce()'d, so
// we don't need to reduce() again
return *this;
}
Fraction Fraction::operator/(const Fraction& rhs) {
Fraction return_value = *this;
return_value.top *= rhs.bottom;
return_value.bottom *= rhs.top;
// Here we do need to reduce()
// because we are changing values to something
// new
return_value.reduce();
return return_value;
}
Fraction& Fraction::operator/=(const Fraction& rhs) {
// Reduce() is called with '/' operator
*this = *this / rhs;
return *this;
}