-
Notifications
You must be signed in to change notification settings - Fork 84
/
Copy pathoperators.cpp
107 lines (81 loc) · 2.75 KB
/
operators.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
#include <iomanip>
#include <iostream>
#include <sstream>
#include <numeric>
class Fraction {
public:
Fraction(int a_num, int a_denom = 1) : m_num(a_num), m_denom(a_denom) {}
std::string str() const {
std::ostringstream oss;
oss << m_num << '/' << m_denom;
return oss.str();
}
friend bool equal( Fraction const & lhs, Fraction const & rhs ) {
return (lhs.m_num==rhs.m_num) && (lhs.m_denom==rhs.m_denom);
}
friend int compare( Fraction const & lhs, Fraction const & rhs ) {
int v1 = lhs.m_num * rhs.m_denom;
int v2 = rhs.m_num * lhs.m_denom;
if (v1 < v2) return -1;
else if (v1 > v2) return 1;
else return 0;
}
friend Fraction multiply( Fraction const & lhs, Fraction const & rhs ) {
return {lhs.m_num * rhs.m_num, lhs.m_denom * rhs.m_denom};
}
Fraction normalized() const {
const int gcd = std::gcd(m_num, m_denom);
return {m_num/gcd, m_denom/gcd};
}
private:
int m_num, m_denom;
};
class TestResultPrinter {
public:
TestResultPrinter( unsigned int a_width ) : m_width(a_width) {}
void process(std::string const & what, bool passed) {
std::cout << std::left << std::setw(m_width) << what << ": " << (passed ? "PASS" : "** FAIL **") << '\n';
}
private:
unsigned int m_width;
};
// This is using the cpp, the C preprocessor to expand a bit of code
// (the what argument) to a pair containing a string representation
// of it and the code itself. That way, print is given a string and a
// value where the string is the code that lead to the value
#define CHECK(printer,what) printer.process(#what, what)
int main() {
// create a fraction with values 3 (which is 3/1) and 1/3
std::cout<<std::endl;
const Fraction three{3};
const Fraction third{1,3};
std::cout<<three.str()<<' '<<third.str()<<'\n';
// equality
std::cout<<std::endl;
TestResultPrinter p1{40};
CHECK(p1,equal(three,three));
CHECK(p1,equal(third,third));
CHECK(p1,equal(three,Fraction{3}));
CHECK(p1,equal(three,Fraction{3,1}));
CHECK(p1,equal(third,Fraction{1,3}));
CHECK(p1,equal(Fraction{3},three));
CHECK(p1,equal(Fraction{1,3},third));
CHECK(p1,!equal(third,Fraction{2,6}));
CHECK(p1,equal(third,Fraction{2,6}.normalized()));
// equivalence
std::cout<<std::endl;
TestResultPrinter p2{32};
CHECK(p2,compare(third,Fraction{2,6})==0);
CHECK(p2,compare(third,Fraction{1,4})>0);
CHECK(p2,compare(third,Fraction{2,4})<0);
// multiply
std::cout<<std::endl;
TestResultPrinter p3{48};
CHECK(p3,equal(multiply(third,2),Fraction{2,3}));
CHECK(p3,equal(multiply(2,third),Fraction{2,3}));
CHECK(p3,compare(multiply(three,third),Fraction{1,1})==0);
CHECK(p3,compare(multiply(3,third),Fraction{1,1})==0);
CHECK(p3,equal(multiply(3,third).normalized(),1));
// end
std::cout<<std::endl;
}