Changeset 541dbc09
 Timestamp:
 Jun 6, 2023, 8:44:14 AM (4 months ago)
 Branches:
 astexperimental, master
 Children:
 77afbb4
 Parents:
 6a93e4d
 Files:

 3 edited
Legend:
 Unmodified
 Added
 Removed

libcfa/src/rational.cfa
r6a93e4d r541dbc09 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 25 18:09:58 202213 // Update Count : 19 412 // Last Modified On : Mon Jun 5 22:49:06 2023 13 // Update Count : 196 14 14 // 15 15 … … 20 20 #pragma GCC visibility push(default) 21 21 22 forall( T  Arithmetic( T ) ) {22 forall( T  arithmetic( T ) ) { 23 23 // helper routines 24 24 … … 39 39 abort  "Invalid rational number construction: denominator cannot be equal to 0."; 40 40 } // exit 41 if ( d < (T){0} ) { d = d; n = n; } 41 if ( d < (T){0} ) { d = d; n = n; } // move sign to numerator 42 42 return gcd( abs( n ), d ); // simplify 43 } // Rationalnumber::simplify43 } // simplify 44 44 45 45 // constructors 46 46 47 void ?{}( Rational(T) & r, zero_t ) {47 void ?{}( rational(T) & r, zero_t ) { 48 48 r{ (T){0}, (T){1} }; 49 49 } // rational 50 50 51 void ?{}( Rational(T) & r, one_t ) {51 void ?{}( rational(T) & r, one_t ) { 52 52 r{ (T){1}, (T){1} }; 53 53 } // rational 54 54 55 void ?{}( Rational(T) & r ) {55 void ?{}( rational(T) & r ) { 56 56 r{ (T){0}, (T){1} }; 57 57 } // rational 58 58 59 void ?{}( Rational(T) & r, T n ) {59 void ?{}( rational(T) & r, T n ) { 60 60 r{ n, (T){1} }; 61 61 } // rational 62 62 63 void ?{}( Rational(T) & r, T n, T d ) {64 T t = simplify( n, d ); // simplify63 void ?{}( rational(T) & r, T n, T d ) { 64 T t = simplify( n, d ); // simplify 65 65 r.[numerator, denominator] = [n / t, d / t]; 66 66 } // rational … … 68 68 // getter for numerator/denominator 69 69 70 T numerator( Rational(T) r ) {70 T numerator( rational(T) r ) { 71 71 return r.numerator; 72 72 } // numerator 73 73 74 T denominator( Rational(T) r ) {74 T denominator( rational(T) r ) { 75 75 return r.denominator; 76 76 } // denominator 77 77 78 [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src ) {78 [ T, T ] ?=?( & [ T, T ] dest, rational(T) src ) { 79 79 return dest = src.[ numerator, denominator ]; 80 80 } // ?=? … … 82 82 // setter for numerator/denominator 83 83 84 T numerator( Rational(T) r, T n ) {84 T numerator( rational(T) r, T n ) { 85 85 T prev = r.numerator; 86 T t = gcd( abs( n ), r.denominator ); 86 T t = gcd( abs( n ), r.denominator ); // simplify 87 87 r.[numerator, denominator] = [n / t, r.denominator / t]; 88 88 return prev; 89 89 } // numerator 90 90 91 T denominator( Rational(T) r, T d ) {91 T denominator( rational(T) r, T d ) { 92 92 T prev = r.denominator; 93 T t = simplify( r.numerator, d ); // simplify93 T t = simplify( r.numerator, d ); // simplify 94 94 r.[numerator, denominator] = [r.numerator / t, d / t]; 95 95 return prev; … … 98 98 // comparison 99 99 100 int ?==?( Rational(T) l, Rational(T) r ) {100 int ?==?( rational(T) l, rational(T) r ) { 101 101 return l.numerator * r.denominator == l.denominator * r.numerator; 102 102 } // ?==? 103 103 104 int ?!=?( Rational(T) l, Rational(T) r ) {104 int ?!=?( rational(T) l, rational(T) r ) { 105 105 return ! ( l == r ); 106 106 } // ?!=? 107 107 108 int ?!=?( Rational(T) l, zero_t ) {109 return ! ( l == ( Rational(T)){ 0 } );108 int ?!=?( rational(T) l, zero_t ) { 109 return ! ( l == (rational(T)){ 0 } ); 110 110 } // ?!=? 111 111 112 int ?<?( Rational(T) l, Rational(T) r ) {112 int ?<?( rational(T) l, rational(T) r ) { 113 113 return l.numerator * r.denominator < l.denominator * r.numerator; 114 114 } // ?<? 115 115 116 int ?<=?( Rational(T) l, Rational(T) r ) {116 int ?<=?( rational(T) l, rational(T) r ) { 117 117 return l.numerator * r.denominator <= l.denominator * r.numerator; 118 118 } // ?<=? 119 119 120 int ?>?( Rational(T) l, Rational(T) r ) {120 int ?>?( rational(T) l, rational(T) r ) { 121 121 return ! ( l <= r ); 122 122 } // ?>? 123 123 124 int ?>=?( Rational(T) l, Rational(T) r ) {124 int ?>=?( rational(T) l, rational(T) r ) { 125 125 return ! ( l < r ); 126 126 } // ?>=? … … 128 128 // arithmetic 129 129 130 Rational(T) +?( Rational(T) r ) {131 return ( Rational(T)){ r.numerator, r.denominator };130 rational(T) +?( rational(T) r ) { 131 return (rational(T)){ r.numerator, r.denominator }; 132 132 } // +? 133 133 134 Rational(T) ?( Rational(T) r ) {135 return ( Rational(T)){ r.numerator, r.denominator };134 rational(T) ?( rational(T) r ) { 135 return (rational(T)){ r.numerator, r.denominator }; 136 136 } // ? 137 137 138 Rational(T) ?+?( Rational(T) l, Rational(T) r ) {138 rational(T) ?+?( rational(T) l, rational(T) r ) { 139 139 if ( l.denominator == r.denominator ) { // special case 140 return ( Rational(T)){ l.numerator + r.numerator, l.denominator };140 return (rational(T)){ l.numerator + r.numerator, l.denominator }; 141 141 } else { 142 return ( Rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };142 return (rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator }; 143 143 } // if 144 144 } // ?+? 145 145 146 Rational(T) ?+=?( Rational(T) & l, Rational(T) r ) {146 rational(T) ?+=?( rational(T) & l, rational(T) r ) { 147 147 l = l + r; 148 148 return l; 149 149 } // ?+? 150 150 151 Rational(T) ?+=?( Rational(T) & l, one_t ) {152 l = l + ( Rational(T)){ 1 };151 rational(T) ?+=?( rational(T) & l, one_t ) { 152 l = l + (rational(T)){ 1 }; 153 153 return l; 154 154 } // ?+? 155 155 156 Rational(T) ??( Rational(T) l, Rational(T) r ) {156 rational(T) ??( rational(T) l, rational(T) r ) { 157 157 if ( l.denominator == r.denominator ) { // special case 158 return ( Rational(T)){ l.numerator  r.numerator, l.denominator };158 return (rational(T)){ l.numerator  r.numerator, l.denominator }; 159 159 } else { 160 return ( Rational(T)){ l.numerator * r.denominator  l.denominator * r.numerator, l.denominator * r.denominator };160 return (rational(T)){ l.numerator * r.denominator  l.denominator * r.numerator, l.denominator * r.denominator }; 161 161 } // if 162 162 } // ?? 163 163 164 Rational(T) ?=?( Rational(T) & l, Rational(T) r ) {164 rational(T) ?=?( rational(T) & l, rational(T) r ) { 165 165 l = l  r; 166 166 return l; 167 167 } // ?? 168 168 169 Rational(T) ?=?( Rational(T) & l, one_t ) {170 l = l  ( Rational(T)){ 1 };169 rational(T) ?=?( rational(T) & l, one_t ) { 170 l = l  (rational(T)){ 1 }; 171 171 return l; 172 172 } // ?? 173 173 174 Rational(T) ?*?( Rational(T) l, Rational(T) r ) {175 return ( Rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator };174 rational(T) ?*?( rational(T) l, rational(T) r ) { 175 return (rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator }; 176 176 } // ?*? 177 177 178 Rational(T) ?*=?( Rational(T) & l, Rational(T) r ) {178 rational(T) ?*=?( rational(T) & l, rational(T) r ) { 179 179 return l = l * r; 180 180 } // ?*? 181 181 182 Rational(T) ?/?( Rational(T) l, Rational(T) r ) {182 rational(T) ?/?( rational(T) l, rational(T) r ) { 183 183 if ( r.numerator < (T){0} ) { 184 184 r.[numerator, denominator] = [r.numerator, r.denominator]; 185 185 } // if 186 return ( Rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator };186 return (rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator }; 187 187 } // ?/? 188 188 189 Rational(T) ?/=?( Rational(T) & l, Rational(T) r ) {189 rational(T) ?/=?( rational(T) & l, rational(T) r ) { 190 190 return l = l / r; 191 191 } // ?/? … … 194 194 195 195 forall( istype &  istream( istype )  { istype & ??( istype &, T & ); } ) 196 istype & ??( istype & is, Rational(T) & r ) {196 istype & ??( istype & is, rational(T) & r ) { 197 197 is  r.numerator  r.denominator; 198 198 T t = simplify( r.numerator, r.denominator ); … … 203 203 204 204 forall( ostype &  ostream( ostype )  { ostype & ??( ostype &, T ); } ) { 205 ostype & ??( ostype & os, Rational(T) r ) {205 ostype & ??( ostype & os, rational(T) r ) { 206 206 return os  r.numerator  '/'  r.denominator; 207 207 } // ?? 208 208 209 void ??( ostype & os, Rational(T) r ) {209 void ??( ostype & os, rational(T) r ) { 210 210 (ostype &)(os  r); ends( os ); 211 211 } // ?? … … 213 213 } // distribution 214 214 215 forall( T  Arithmetic( T )  { T ?\?( T, unsigned long ); } ) {216 Rational(T) ?\?( Rational(T) x, long int y ) {215 forall( T  arithmetic( T )  { T ?\?( T, unsigned long ); } ) { 216 rational(T) ?\?( rational(T) x, long int y ) { 217 217 if ( y < 0 ) { 218 return ( Rational(T)){ x.denominator \ y, x.numerator \ y };218 return (rational(T)){ x.denominator \ y, x.numerator \ y }; 219 219 } else { 220 return ( Rational(T)){ x.numerator \ y, x.denominator \ y };220 return (rational(T)){ x.numerator \ y, x.denominator \ y }; 221 221 } // if 222 222 } // ?\? 223 223 224 Rational(T) ?\=?( Rational(T) & x, long int y ) {224 rational(T) ?\=?( rational(T) & x, long int y ) { 225 225 return x = x \ y; 226 226 } // ?\? … … 229 229 // conversion 230 230 231 forall( T  Arithmetic( T )  { double convert( T ); } )232 double widen( Rational(T) r ) {231 forall( T  arithmetic( T )  { double convert( T ); } ) 232 double widen( rational(T) r ) { 233 233 return convert( r.numerator ) / convert( r.denominator ); 234 234 } // widen 235 235 236 forall( T  Arithmetic( T )  { double convert( T ); T convert( double ); } )237 Rational(T) narrow( double f, T md ) {236 forall( T  arithmetic( T )  { double convert( T ); T convert( double ); } ) 237 rational(T) narrow( double f, T md ) { 238 238 // http://www.ics.uci.edu/~eppstein/numth/frap.c 239 if ( md <= (T){1} ) { // maximum fractional digits too small?240 return ( Rational(T)){ convert( f ), (T){1}};// truncate fraction239 if ( md <= (T){1} ) { // maximum fractional digits too small? 240 return (rational(T)){ convert( f ), (T){1}}; // truncate fraction 241 241 } // if 242 242 … … 260 260 if ( f > (double)0x7FFFFFFF ) break; // representation failure 261 261 } // for 262 return ( Rational(T)){ m00, m10 };262 return (rational(T)){ m00, m10 }; 263 263 } // narrow 264 264 
libcfa/src/rational.hfa
r6a93e4d r541dbc09 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Tue Jul 20 17:45:29 202115 // Update Count : 11 814 // Last Modified On : Mon Jun 5 22:49:05 2023 15 // Update Count : 119 16 16 // 17 17 … … 19 19 20 20 #include "iostream.hfa" 21 #include "math.trait.hfa" // Arithmetic21 #include "math.trait.hfa" // arithmetic 22 22 23 23 // implementation 24 24 25 forall( T  Arithmetic( T ) ) {26 struct Rational {25 forall( T  arithmetic( T ) ) { 26 struct rational { 27 27 T numerator, denominator; // invariant: denominator > 0 28 }; // Rational28 }; // rational 29 29 30 30 // constructors 31 31 32 void ?{}( Rational(T) & r );33 void ?{}( Rational(T) & r, zero_t );34 void ?{}( Rational(T) & r, one_t );35 void ?{}( Rational(T) & r, T n );36 void ?{}( Rational(T) & r, T n, T d );32 void ?{}( rational(T) & r ); 33 void ?{}( rational(T) & r, zero_t ); 34 void ?{}( rational(T) & r, one_t ); 35 void ?{}( rational(T) & r, T n ); 36 void ?{}( rational(T) & r, T n, T d ); 37 37 38 38 // numerator/denominator getter 39 39 40 T numerator( Rational(T) r );41 T denominator( Rational(T) r );42 [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src );40 T numerator( rational(T) r ); 41 T denominator( rational(T) r ); 42 [ T, T ] ?=?( & [ T, T ] dest, rational(T) src ); 43 43 44 44 // numerator/denominator setter 45 45 46 T numerator( Rational(T) r, T n );47 T denominator( Rational(T) r, T d );46 T numerator( rational(T) r, T n ); 47 T denominator( rational(T) r, T d ); 48 48 49 49 // comparison 50 50 51 int ?==?( Rational(T) l, Rational(T) r );52 int ?!=?( Rational(T) l, Rational(T) r );53 int ?!=?( Rational(T) l, zero_t ); // => !54 int ?<?( Rational(T) l, Rational(T) r );55 int ?<=?( Rational(T) l, Rational(T) r );56 int ?>?( Rational(T) l, Rational(T) r );57 int ?>=?( Rational(T) l, Rational(T) r );51 int ?==?( rational(T) l, rational(T) r ); 52 int ?!=?( rational(T) l, rational(T) r ); 53 int ?!=?( rational(T) l, zero_t ); // => ! 54 int ?<?( rational(T) l, rational(T) r ); 55 int ?<=?( rational(T) l, rational(T) r ); 56 int ?>?( rational(T) l, rational(T) r ); 57 int ?>=?( rational(T) l, rational(T) r ); 58 58 59 59 // arithmetic 60 60 61 Rational(T) +?( Rational(T) r );62 Rational(T) ?( Rational(T) r );63 Rational(T) ?+?( Rational(T) l, Rational(T) r );64 Rational(T) ?+=?( Rational(T) & l, Rational(T) r );65 Rational(T) ?+=?( Rational(T) & l, one_t ); // => ++?, ?++66 Rational(T) ??( Rational(T) l, Rational(T) r );67 Rational(T) ?=?( Rational(T) & l, Rational(T) r );68 Rational(T) ?=?( Rational(T) & l, one_t ); // => ?, ?69 Rational(T) ?*?( Rational(T) l, Rational(T) r );70 Rational(T) ?*=?( Rational(T) & l, Rational(T) r );71 Rational(T) ?/?( Rational(T) l, Rational(T) r );72 Rational(T) ?/=?( Rational(T) & l, Rational(T) r );61 rational(T) +?( rational(T) r ); 62 rational(T) ?( rational(T) r ); 63 rational(T) ?+?( rational(T) l, rational(T) r ); 64 rational(T) ?+=?( rational(T) & l, rational(T) r ); 65 rational(T) ?+=?( rational(T) & l, one_t ); // => ++?, ?++ 66 rational(T) ??( rational(T) l, rational(T) r ); 67 rational(T) ?=?( rational(T) & l, rational(T) r ); 68 rational(T) ?=?( rational(T) & l, one_t ); // => ?, ? 69 rational(T) ?*?( rational(T) l, rational(T) r ); 70 rational(T) ?*=?( rational(T) & l, rational(T) r ); 71 rational(T) ?/?( rational(T) l, rational(T) r ); 72 rational(T) ?/=?( rational(T) & l, rational(T) r ); 73 73 74 74 // I/O 75 75 forall( istype &  istream( istype )  { istype & ??( istype &, T & ); } ) 76 istype & ??( istype &, Rational(T) & );76 istype & ??( istype &, rational(T) & ); 77 77 78 78 forall( ostype &  ostream( ostype )  { ostype & ??( ostype &, T ); } ) { 79 ostype & ??( ostype &, Rational(T) );80 void ??( ostype &, Rational(T) );79 ostype & ??( ostype &, rational(T) ); 80 void ??( ostype &, rational(T) ); 81 81 } // distribution 82 82 } // distribution 83 83 84 forall( T  Arithmetic( T )  { T ?\?( T, unsigned long ); } ) {85 Rational(T) ?\?( Rational(T) x, long int y );86 Rational(T) ?\=?( Rational(T) & x, long int y );84 forall( T  arithmetic( T )  { T ?\?( T, unsigned long ); } ) { 85 rational(T) ?\?( rational(T) x, long int y ); 86 rational(T) ?\=?( rational(T) & x, long int y ); 87 87 } // distribution 88 88 89 89 // conversion 90 forall( T  Arithmetic( T )  { double convert( T ); } )91 double widen( Rational(T) r );92 forall( T  Arithmetic( T )  { double convert( T ); T convert( double );} )93 Rational(T) narrow( double f, T md );90 forall( T  arithmetic( T )  { double convert( T ); } ) 91 double widen( rational(T) r ); 92 forall( T  arithmetic( T )  { double convert( T ); T convert( double );} ) 93 rational(T) narrow( double f, T md ); 94 94 95 95 // Local Variables: // 
tests/rational.cfa
r6a93e4d r541dbc09 10 10 // Created On : Mon Mar 28 08:43:12 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 20 18:13:40 202113 // Update Count : 10 712 // Last Modified On : Mon Jun 5 22:58:09 2023 13 // Update Count : 108 14 14 // 15 15 … … 19 19 #include <fstream.hfa> 20 20 21 typedef Rational(int) RatInt;21 typedef rational(int) rat_int; 22 22 double convert( int i ) { return (double)i; } // used by narrow/widen 23 23 int convert( double d ) { return (int)d; } … … 25 25 int main() { 26 26 sout  "constructor"; 27 RatInt a = { 3 }, b = { 4 }, c, d = 0, e = 1;27 rat_int a = { 3 }, b = { 4 }, c, d = 0, e = 1; 28 28 sout  "a : "  a  "b : "  b  "c : "  c  "d : "  d  "e : "  e; 29 29 30 a = ( RatInt){ 4, 8 };31 b = ( RatInt){ 5, 7 };30 a = (rat_int){ 4, 8 }; 31 b = (rat_int){ 5, 7 }; 32 32 sout  "a : "  a  "b : "  b; 33 a = ( RatInt){ 2, 3 };34 b = ( RatInt){ 3, 2 };33 a = (rat_int){ 2, 3 }; 34 b = (rat_int){ 3, 2 }; 35 35 sout  "a : "  a  "b : "  b; 36 a = ( RatInt){ 2, 3 };37 b = ( RatInt){ 3, 2 };36 a = (rat_int){ 2, 3 }; 37 b = (rat_int){ 3, 2 }; 38 38 sout  "a : "  a  "b : "  b; 39 39 sout  nl; 40 40 41 41 sout  "comparison"; 42 a = ( RatInt){ 2 };43 b = ( RatInt){ 3, 2 };42 a = (rat_int){ 2 }; 43 b = (rat_int){ 3, 2 }; 44 44 sout  "a : "  a  "b : "  b; 45 sout  "a == 0 : "  a == ( Rational(int)){0}; // FIX ME46 sout  "a == 1 : "  a == ( Rational(int)){1}; // FIX ME45 sout  "a == 0 : "  a == (rational(int)){0}; // FIX ME 46 sout  "a == 1 : "  a == (rational(int)){1}; // FIX ME 47 47 sout  "a != 0 : "  a != 0; 48 48 sout  "! a : "  ! a; … … 73 73 74 74 sout  "conversion"; 75 a = ( RatInt){ 3, 4 };75 a = (rat_int){ 3, 4 }; 76 76 sout  widen( a ); 77 a = ( RatInt){ 1, 7 };77 a = (rat_int){ 1, 7 }; 78 78 sout  widen( a ); 79 a = ( RatInt){ 355, 113 };79 a = (rat_int){ 355, 113 }; 80 80 sout  widen( a ); 81 81 sout  narrow( 0.75, 4 ); … … 90 90 91 91 sout  "more tests"; 92 RatInt x = { 1, 2 }, y = { 2 };92 rat_int x = { 1, 2 }, y = { 2 }; 93 93 sout  x  y; 94 94 sout  x > y; … … 96 96 sout  y  denominator( y, 2 )  y; 97 97 98 RatInt z = { 0, 5 };98 rat_int z = { 0, 5 }; 99 99 sout  z; 100 100 101 101 sout  x  numerator( x, 0 )  x; 102 102 103 x = ( RatInt){ 1, MAX } + (RatInt){ 1, MAX };103 x = (rat_int){ 1, MAX } + (rat_int){ 1, MAX }; 104 104 sout  x; 105 x = ( RatInt){ 3, MAX } + (RatInt){ 2, MAX };105 x = (rat_int){ 3, MAX } + (rat_int){ 2, MAX }; 106 106 sout  x; 107 107
Note: See TracChangeset
for help on using the changeset viewer.