source: src/examples/rational.cc@ 8b52686

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 8b52686 was 53ba273, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

switch from std=c99 to std=gnu99, update latex macros, refrat and extend user manual, update limits/iostream/fstream, add rational numbers

  • Property mode set to 100644
File size: 5.4 KB
Line 
1#include "rationalnumber.h"
2
3#include <iostream>
4#include <cstdlib> // exit
5using namespace std;
6
7static struct {
8 int gcd, con, copy, des, assn, rel, add, sub, mul, div, in, out;
9} stats; // implicitly initialized to 0
10
11static int gcd( int a, int b ) {
12 for ( ;; ) {
13 int r = a % b;
14 if ( r == 0 ) break;
15 a = b;
16 b = r;
17 } // for
18 stats.gcd += 1;
19 return b;
20} // gcd
21
22void Rationalnumber::statistics() {
23 cerr
24 << "gcd:" << stats.gcd << '\t'
25 << "con:" << stats.con << '\t'
26 << "copy:" << stats.copy << '\t'
27 << "des:" << stats.des << '\t'
28 << "assn:" << stats.assn << '\t'
29 << "rel:" << stats.rel << '\t'
30 << "add:" << stats.add << '\t'
31 << "sub:" << stats.sub << '\t'
32 << "mul:" << stats.mul << '\t'
33 << "div:" << stats.div << '\t'
34 << "in:" << stats.in << '\t'
35 << "out:" << stats.out
36 << endl;
37} // Rationalnumber::statistics
38
39bool Rationalnumber::eq( Rationalnumber &r ) {
40 return num * r.denom == denom * r.num;
41} // Rationalnumber::Rationalnumber::eq
42
43bool Rationalnumber::lt( Rationalnumber &r ) {
44 //int temp1 = denom * r.denom, temp2 = num * r.denom, temp3 = denom * r.num;
45 //return temp1 > 0 && temp2 < temp3 || temp1 < 0 && temp2 > temp3;
46 // if denominator is always > 0, only this check is necessary
47 return num * r.denom < denom * r.num;
48} // Rationalnumber::Rationalnumber::lt
49
50void Rationalnumber::common1( int n, int d ) {
51 num = n;
52 denom = d;
53 stats.con += 1;
54} // Rationalnumber::common1
55
56int Rationalnumber::common2( int &n, int &d ) {
57 if ( d == 0 ) {
58 cerr << "Invalid rational number construction: denominator cannot be equal to 0." << endl;
59 exit( EXIT_FAILURE );
60 } // exit
61 if ( d < 0 ) { d = -d; n = -n; } // move sign to numerator
62 return gcd( abs( n ), d ); // simplify
63} // Rationalnumber::common2
64
65Rationalnumber::Rationalnumber() {
66 common1( 0, 1 );
67} // Rationalnumber::Rationalnumber
68
69Rationalnumber::Rationalnumber( int n ) {
70 common1( n, 1 );
71} // Rationalnumber::Rationalnumber
72
73Rationalnumber::Rationalnumber( int n, int d ) {
74 int temp = common2( n, d );
75 common1( n / temp, d / temp );
76} // Rationalnumber::Rationalnumber
77
78Rationalnumber::Rationalnumber( const Rationalnumber &c ) {
79 num = c.num;
80 denom = c.denom;
81 stats.copy += 1;
82} // Rationalnumber::Rationalnumber
83
84Rationalnumber::~Rationalnumber() {
85 stats.des += 1;
86} // Rationalnumber::~Rationalnumber
87
88Rationalnumber &Rationalnumber::operator=( const Rationalnumber &r ) {
89 num = r.num;
90 denom = r.denom;
91 stats.assn += 1;
92 return *this;
93} // Rationalnumber::operator=
94
95int Rationalnumber::numerator() const {
96 return num;
97} // Rationalnumber::numerator
98
99int Rationalnumber::numerator( int n ) {
100 int prev = num;
101 int temp = gcd( abs( n ), denom ); // simplify
102 num = n / temp;
103 denom = denom / temp;
104 return prev;
105} // Rationalnumber::numerator
106
107int Rationalnumber::denominator() const {
108 return denom;
109} // Rationalnumber::denominator
110
111int Rationalnumber::denominator( int d ) {
112 int prev = denom;
113 int temp = common2( num, d );
114 num = num / temp;
115 denom = d / temp;
116 return prev;
117} // Rationalnumber::denominator
118
119bool operator==( Rationalnumber l, Rationalnumber r ) {
120 stats.rel += 1;
121 return l.eq( r );
122} // operator==
123
124bool operator!=( Rationalnumber l, Rationalnumber r ) {
125 stats.rel += 1;
126 return ! ( l.eq( r ) );
127} // operator!=
128
129bool operator<( Rationalnumber l, Rationalnumber r ) {
130 stats.rel += 1;
131 return l.lt( r );
132} // operator<
133
134bool operator<=( Rationalnumber l, Rationalnumber r ) {
135 stats.rel += 1;
136 return l.lt( r ) || l.eq( r );
137} // operator<=
138
139bool operator>( Rationalnumber l, Rationalnumber r ) {
140 stats.rel += 1;
141 return ! ( l.lt( r ) || l.eq( r ) );
142} // operator>
143
144bool operator>=( Rationalnumber l, Rationalnumber r ) {
145 stats.rel += 1;
146 return ! ( l.lt( r ) );
147} // operator>=
148
149Rationalnumber Rationalnumber::operator-() {
150 return Rationalnumber( -num, denom );
151} // Rationalnumber::operator-
152
153Rationalnumber operator+( Rationalnumber l, Rationalnumber r ) {
154 stats.add += 1;
155 if ( l.denom == r.denom ) { // special case
156 return Rationalnumber( l.num + r.num, l.denom );
157 } else {
158 return Rationalnumber( l.num * r.denom + l.denom * r.num, l.denom * r.denom );
159 } // if
160} // operator+
161
162Rationalnumber operator-( Rationalnumber l, Rationalnumber r ) {
163 stats.sub += 1;
164 if ( l.denom == r.denom ) { // special case
165 return Rationalnumber( l.num - r.num, l.denom );
166 } else {
167 return Rationalnumber( l.num * r.denom - l.denom * r.num, l.denom * r.denom );
168 } // if
169} // operator-
170
171Rationalnumber operator*( Rationalnumber l, Rationalnumber r ) {
172 stats.mul += 1;
173 return Rationalnumber( l.num * r.num, l.denom * r.denom );
174} // operator*
175
176Rationalnumber operator/( Rationalnumber l, Rationalnumber r ) {
177 stats.div += 1;
178 if ( r.num < 0 ) { r.num = -r.num; r.denom = -r.denom; }
179 return Rationalnumber( l.num * r.denom, l.denom * r.num );
180} // operator/
181
182istream &operator>>( istream &is, Rationalnumber &r ) {
183 stats.in += 1;
184 is >> r.num >> r.denom;
185 int temp = Rationalnumber::common2( r.num, r.denom );
186 r.num /= temp;
187 r.denom /= temp;
188 return is;
189} // operator>>
190
191ostream &operator<<( ostream &os, Rationalnumber r ) {
192 stats.out += 1;
193 return os << r.num << "/" << r.denom;
194} // operator<<
195
196// Local Variables: //
197// compile-command: "make rationalnumber" //
198// End: //
Note: See TracBrowser for help on using the repository browser.