source: src/examples/rational.cc @ 356bb95

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 356bb95 was 53ba273, checked in by Peter A. Buhr <pabuhr@…>, 8 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.