Skip to content

Commit 81b89c5

Browse files
committed
solved operators exercise
1 parent 7cb6e13 commit 81b89c5

File tree

1 file changed

+110
-80
lines changed

1 file changed

+110
-80
lines changed

exercises/operators/operators.cpp

Lines changed: 110 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,89 +3,119 @@
33
#include <numeric>
44

55
class Fraction {
6-
public:
7-
// TODO: constructors and operators
8-
9-
private:
10-
void normalize() {
11-
const int gcd = std::gcd(m_num, m_denom);
12-
m_num /= gcd;
13-
m_denom /= gcd;
14-
}
15-
16-
unsigned int m_num, m_denom;
6+
public:
7+
Fraction() = delete;
8+
Fraction(int num)
9+
: m_num(num)
10+
, m_denom(1)
11+
{
12+
}
13+
Fraction(int num, int denom)
14+
: m_num(num)
15+
, m_denom(denom)
16+
{
17+
normalize();
18+
}
19+
20+
Fraction& operator*=(int n)
21+
{
22+
m_num *= n;
23+
normalize();
24+
return *this;
25+
}
26+
Fraction& operator*=(Fraction const& other)
27+
{
28+
m_num *= other.m_num;
29+
m_denom *= other.m_denom;
30+
normalize();
31+
return *this;
32+
}
33+
friend Fraction operator*(Fraction f, int i) { return f *= i; }
34+
friend Fraction operator*(int i, Fraction const& f) { return f * i; }
35+
friend Fraction operator*(Fraction a, Fraction const& b) { return a *= b; }
36+
37+
friend bool operator==(Fraction const& a, Fraction const& b)
38+
{
39+
return a.m_num == b.m_num && a.m_denom == b.m_denom;
40+
}
41+
friend bool operator!=(Fraction const& a, Fraction const& b) { return !(a == b); }
42+
43+
friend bool operator<(Fraction const& a, Fraction const& b)
44+
{
45+
return a.m_num * b.m_denom < b.m_num * a.m_denom;
46+
}
47+
friend bool operator>(Fraction const& a, Fraction const& b) { return b < a; }
48+
friend bool operator<=(Fraction const& a, Fraction const& b) { return !(a > b); }
49+
friend bool operator>=(Fraction const& a, Fraction const& b) { return !(a < b); }
50+
51+
friend std::ostream& operator<<(std::ostream& os, Fraction const& frac)
52+
{
53+
os << "[" << frac.m_num << "," << frac.m_denom << "]";
54+
return os;
55+
}
56+
57+
private:
58+
void normalize()
59+
{
60+
const int gcd = std::gcd(m_num, m_denom);
61+
m_num /= gcd;
62+
m_denom /= gcd;
63+
}
64+
65+
unsigned int m_num, m_denom;
1766
};
1867

19-
// TODO: operators
20-
21-
22-
void printAndCheck(std::string const & what, Fraction const & result, Fraction const & expected) {
23-
const bool passed = result == expected;
24-
std::cout << std::left << std::setw(40) << what << ": " << (passed ? "PASS" : "** FAIL **") << " " << result << "\n";
68+
void printAndCheck(std::string const& what, Fraction const& result, Fraction const& expected)
69+
{
70+
const bool passed = result == expected;
71+
std::cout << std::left << std::setw(40) << what << ": " << (passed ? "PASS" : "** FAIL **") << " " << result << "\n";
2572
}
26-
void printAndCheck(std::string const & what, bool result, bool expected) {
27-
const bool passed = result == expected;
28-
std::cout << std::left << std::setw(40) << what << ": " << (passed ? "PASS" : "** FAIL **") << " " << result << "\n";
73+
void printAndCheck(std::string const& what, bool result, bool expected)
74+
{
75+
const bool passed = result == expected;
76+
std::cout << std::left << std::setw(40) << what << ": " << (passed ? "PASS" : "** FAIL **") << " " << result << "\n";
2977
}
3078

31-
int main() {
32-
// create a fraction with values 3 (which is 3/1) and 1/3
33-
const Fraction three{3};
34-
const Fraction athird{1, 3};
35-
36-
// print the fractions
37-
std::cout << "Three: " << three << '\n';
38-
std::cout << "One third: " << athird << '\n';
39-
40-
// multiply fraction with an int
41-
// the printAndCheck function requires operator<< and operator==:
42-
printAndCheck("One third times two", athird * 2, Fraction{2, 3});
43-
// ensure symmetry
44-
printAndCheck("Two times one third", 2 * athird, Fraction{2, 3});
45-
46-
// multiply two fractions
47-
printAndCheck("Three times one third", three * athird, Fraction{1, 1});
48-
// normalize the fraction after multiplication so the above statement
49-
// prints 1/1 instead of e.g. 3/3
50-
printAndCheck("Three times one third", 3 * athird, Fraction{1, 1});
51-
52-
// multiply in place
53-
Fraction f = athird;
54-
f *= 2;
55-
printAndCheck("One third times two", f, Fraction{2, 3});
56-
57-
f *= athird;
58-
printAndCheck("Two third times one third", f, Fraction{2, 9});
59-
60-
// you might have some redundancy between the implementation of operator* and
61-
// operator*=. Can you refactor your code and implement operator* in terms of
62-
// operator*=?
63-
64-
std::cout << std::boolalpha; // print bools as 'true' or 'false' from now on
65-
66-
// more equality comparisons
67-
printAndCheck("One third == one third", (athird == Fraction{1, 3}), true);
68-
printAndCheck("One third != one forth", (athird != Fraction{1, 4}), true);
69-
printAndCheck("One third == two sixth", (athird == Fraction{2, 6}), true);
70-
printAndCheck("One third != three sixth", (athird != Fraction{3, 6}), true);
71-
// try to implement operator!= in terms of operator==
72-
73-
// more comparisons
74-
const Fraction afourth{1, 4};
75-
printAndCheck("athird < athird", (athird < athird), false);
76-
printAndCheck("afourth < athird", (afourth < athird), true);
77-
printAndCheck("athird <= athird", (athird <= athird), true);
78-
printAndCheck("athird <= afourth", (athird <= afourth), false);
79-
printAndCheck("athird > athird", (athird > athird), false);
80-
printAndCheck("afourth > athird", (afourth > athird), false);
81-
printAndCheck("athird >= athird", (athird >= athird), true);
82-
printAndCheck("athird >= afourth", (athird >= afourth), true);
83-
// the operators <=, >= and > can typically be implemented just in terms of
84-
// operator<. Can you do this as well? ;)
85-
86-
// take aways on operators:
87-
// * we can very often implement an arithemtic operator@ in terms of
88-
// operator@=
89-
// * it usually suffices to implement operator< and operator== and derive the
90-
// other relational operators from them. C++20 will do part of this automatically.
79+
int main()
80+
{
81+
const Fraction three { 3 };
82+
const Fraction athird { 1, 3 };
83+
84+
std::cout << "Three: " << three << '\n';
85+
std::cout << "One third: " << athird << '\n';
86+
87+
// multiply fraction with an int
88+
printAndCheck("One third times two", athird * 2, Fraction { 2, 3 });
89+
printAndCheck("Two times one third", 2 * athird, Fraction { 2, 3 });
90+
91+
// multiply two fractions
92+
printAndCheck("Three times one third", three * athird, Fraction { 1, 1 });
93+
printAndCheck("Three times one third", 3 * athird, Fraction { 1, 1 });
94+
95+
// multiply in place
96+
Fraction f = athird;
97+
f *= 2;
98+
printAndCheck("One third times two", f, Fraction { 2, 3 });
99+
100+
f *= athird;
101+
printAndCheck("Two third times one third", f, Fraction { 2, 9 });
102+
103+
std::cout << std::boolalpha; // print bools as 'true' or 'false' from now on
104+
105+
// more equality comparisons
106+
printAndCheck("One third == one third", (athird == Fraction { 1, 3 }), true);
107+
printAndCheck("One third != one forth", (athird != Fraction { 1, 4 }), true);
108+
printAndCheck("One third == two sixth", (athird == Fraction { 2, 6 }), true);
109+
printAndCheck("One third != three sixth", (athird != Fraction { 3, 6 }), true);
110+
111+
// more comparisons
112+
const Fraction afourth { 1, 4 };
113+
printAndCheck("athird < athird", (athird < athird), false);
114+
printAndCheck("afourth < athird", (afourth < athird), true);
115+
printAndCheck("athird <= athird", (athird <= athird), true);
116+
printAndCheck("athird <= afourth", (athird <= afourth), false);
117+
printAndCheck("athird > athird", (athird > athird), false);
118+
printAndCheck("afourth > athird", (afourth > athird), false);
119+
printAndCheck("athird >= athird", (athird >= athird), true);
120+
printAndCheck("athird >= afourth", (athird >= afourth), true);
91121
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy