Ignore:
Timestamp:
Jul 20, 2021, 6:30:29 PM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
d30804a
Parents:
8477fc4
Message:

formatting, use new math trait in rational numbers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/rational.cfa

    r8477fc4 r5dc4c7e  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb  8 17:56:36 2020
    13 // Update Count     : 187
     12// Last Modified On : Tue Jul 20 16:30:06 2021
     13// Update Count     : 193
    1414//
    1515
     
    1818#include "stdlib.hfa"
    1919
    20 forall( RationalImpl | arithmetic( RationalImpl ) ) {
     20forall( T | Arithmetic( T ) ) {
    2121        // helper routines
    2222
    2323        // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce
    2424        // rationals.  alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
    25         static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
     25        static T gcd( T a, T b ) {
    2626                for ( ;; ) {                                                                    // Euclid's algorithm
    27                         RationalImpl r = a % b;
    28                   if ( r == (RationalImpl){0} ) break;
     27                        T r = a % b;
     28                  if ( r == (T){0} ) break;
    2929                        a = b;
    3030                        b = r;
     
    3333        } // gcd
    3434
    35         static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) {
    36                 if ( d == (RationalImpl){0} ) {
     35        static T simplify( T & n, T & d ) {
     36                if ( d == (T){0} ) {
    3737                        abort | "Invalid rational number construction: denominator cannot be equal to 0.";
    3838                } // exit
    39                 if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator
     39                if ( d < (T){0} ) { d = -d; n = -n; } // move sign to numerator
    4040                return gcd( abs( n ), d );                                              // simplify
    4141        } // Rationalnumber::simplify
     
    4343        // constructors
    4444
    45         void ?{}( Rational(RationalImpl) & r ) {
    46                 r{ (RationalImpl){0}, (RationalImpl){1} };
    47         } // rational
    48 
    49         void ?{}( Rational(RationalImpl) & r, RationalImpl n ) {
    50                 r{ n, (RationalImpl){1} };
    51         } // rational
    52 
    53         void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) {
    54                 RationalImpl t = simplify( n, d );                              // simplify
     45        void ?{}( Rational(T) & r, zero_t ) {
     46                r{ (T){0}, (T){1} };
     47        } // rational
     48
     49        void ?{}( Rational(T) & r, one_t ) {
     50                r{ (T){1}, (T){1} };
     51        } // rational
     52
     53        void ?{}( Rational(T) & r ) {
     54                r{ (T){0}, (T){1} };
     55        } // rational
     56
     57        void ?{}( Rational(T) & r, T n ) {
     58                r{ n, (T){1} };
     59        } // rational
     60
     61        void ?{}( Rational(T) & r, T n, T d ) {
     62                T t = simplify( n, d );                         // simplify
    5563                r.[numerator, denominator] = [n / t, d / t];
    5664        } // rational
    5765
    58         void ?{}( Rational(RationalImpl) & r, zero_t ) {
    59                 r{ (RationalImpl){0}, (RationalImpl){1} };
    60         } // rational
    61 
    62         void ?{}( Rational(RationalImpl) & r, one_t ) {
    63                 r{ (RationalImpl){1}, (RationalImpl){1} };
    64         } // rational
    65 
    6666        // getter for numerator/denominator
    6767
    68         RationalImpl numerator( Rational(RationalImpl) r ) {
     68        T numerator( Rational(T) r ) {
    6969                return r.numerator;
    7070        } // numerator
    7171
    72         RationalImpl denominator( Rational(RationalImpl) r ) {
     72        T denominator( Rational(T) r ) {
    7373                return r.denominator;
    7474        } // denominator
    7575
    76         [ RationalImpl, RationalImpl ] ?=?( & [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ) {
     76        [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src ) {
    7777                return dest = src.[ numerator, denominator ];
    7878        } // ?=?
     
    8080        // setter for numerator/denominator
    8181
    82         RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ) {
    83                 RationalImpl prev = r.numerator;
    84                 RationalImpl t = gcd( abs( n ), r.denominator ); // simplify
     82        T numerator( Rational(T) r, T n ) {
     83                T prev = r.numerator;
     84                T t = gcd( abs( n ), r.denominator ); // simplify
    8585                r.[numerator, denominator] = [n / t, r.denominator / t];
    8686                return prev;
    8787        } // numerator
    8888
    89         RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ) {
    90                 RationalImpl prev = r.denominator;
    91                 RationalImpl t = simplify( r.numerator, d );    // simplify
     89        T denominator( Rational(T) r, T d ) {
     90                T prev = r.denominator;
     91                T t = simplify( r.numerator, d );       // simplify
    9292                r.[numerator, denominator] = [r.numerator / t, d / t];
    9393                return prev;
     
    9696        // comparison
    9797
    98         int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     98        int ?==?( Rational(T) l, Rational(T) r ) {
    9999                return l.numerator * r.denominator == l.denominator * r.numerator;
    100100        } // ?==?
    101101
    102         int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     102        int ?!=?( Rational(T) l, Rational(T) r ) {
    103103                return ! ( l == r );
    104104        } // ?!=?
    105105
    106         int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     106        int ?!=?( Rational(T) l, zero_t ) {
     107                return ! ( l == (Rational(T)){ 0 } );
     108        } // ?!=?
     109
     110        int ?<?( Rational(T) l, Rational(T) r ) {
    107111                return l.numerator * r.denominator < l.denominator * r.numerator;
    108112        } // ?<?
    109113
    110         int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     114        int ?<=?( Rational(T) l, Rational(T) r ) {
    111115                return l.numerator * r.denominator <= l.denominator * r.numerator;
    112116        } // ?<=?
    113117
    114         int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     118        int ?>?( Rational(T) l, Rational(T) r ) {
    115119                return ! ( l <= r );
    116120        } // ?>?
    117121
    118         int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     122        int ?>=?( Rational(T) l, Rational(T) r ) {
    119123                return ! ( l < r );
    120124        } // ?>=?
     
    122126        // arithmetic
    123127
    124         Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
    125                 return (Rational(RationalImpl)){ r.numerator, r.denominator };
     128        Rational(T) +?( Rational(T) r ) {
     129                return (Rational(T)){ r.numerator, r.denominator };
    126130        } // +?
    127131
    128         Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
    129                 return (Rational(RationalImpl)){ -r.numerator, r.denominator };
     132        Rational(T) -?( Rational(T) r ) {
     133                return (Rational(T)){ -r.numerator, r.denominator };
    130134        } // -?
    131135
    132         Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     136        Rational(T) ?+?( Rational(T) l, Rational(T) r ) {
    133137                if ( l.denominator == r.denominator ) {                 // special case
    134                         return (Rational(RationalImpl)){ l.numerator + r.numerator, l.denominator };
     138                        return (Rational(T)){ l.numerator + r.numerator, l.denominator };
    135139                } else {
    136                         return (Rational(RationalImpl)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
     140                        return (Rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
    137141                } // if
    138142        } // ?+?
    139143
    140         Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     144        Rational(T) ?+=?( Rational(T) & l, Rational(T) r ) {
     145                l = l + r;
     146                return l;
     147        } // ?+?
     148
     149        Rational(T) ?+=?( Rational(T) & l, one_t ) {
     150                l = l + (Rational(T)){ 1 };
     151                return l;
     152        } // ?+?
     153
     154        Rational(T) ?-?( Rational(T) l, Rational(T) r ) {
    141155                if ( l.denominator == r.denominator ) {                 // special case
    142                         return (Rational(RationalImpl)){ l.numerator - r.numerator, l.denominator };
     156                        return (Rational(T)){ l.numerator - r.numerator, l.denominator };
    143157                } else {
    144                         return (Rational(RationalImpl)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
     158                        return (Rational(T)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
    145159                } // if
    146160        } // ?-?
    147161
    148         Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    149                 return (Rational(RationalImpl)){ l.numerator * r.numerator, l.denominator * r.denominator };
     162        Rational(T) ?-=?( Rational(T) & l, Rational(T) r ) {
     163                l = l - r;
     164                return l;
     165        } // ?-?
     166
     167        Rational(T) ?-=?( Rational(T) & l, one_t ) {
     168                l = l - (Rational(T)){ 1 };
     169                return l;
     170        } // ?-?
     171
     172        Rational(T) ?*?( Rational(T) l, Rational(T) r ) {
     173                return (Rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator };
    150174        } // ?*?
    151175
    152         Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    153                 if ( r.numerator < (RationalImpl){0} ) {
     176        Rational(T) ?*=?( Rational(T) & l, Rational(T) r ) {
     177                return l = l * r;
     178        } // ?*?
     179
     180        Rational(T) ?/?( Rational(T) l, Rational(T) r ) {
     181                if ( r.numerator < (T){0} ) {
    154182                        r.[numerator, denominator] = [-r.numerator, -r.denominator];
    155183                } // if
    156                 return (Rational(RationalImpl)){ l.numerator * r.denominator, l.denominator * r.numerator };
     184                return (Rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator };
    157185        } // ?/?
    158186
     187        Rational(T) ?/=?( Rational(T) & l, Rational(T) r ) {
     188                return l = l / r;
     189        } // ?/?
     190
    159191        // I/O
    160192
    161         forall( istype & | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
    162         istype & ?|?( istype & is, Rational(RationalImpl) & r ) {
     193        forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } )
     194        istype & ?|?( istype & is, Rational(T) & r ) {
    163195                is | r.numerator | r.denominator;
    164                 RationalImpl t = simplify( r.numerator, r.denominator );
     196                T t = simplify( r.numerator, r.denominator );
    165197                r.numerator /= t;
    166198                r.denominator /= t;
     
    168200        } // ?|?
    169201
    170         forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) {
    171                 ostype & ?|?( ostype & os, Rational(RationalImpl) r ) {
     202        forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) {
     203                ostype & ?|?( ostype & os, Rational(T) r ) {
    172204                        return os | r.numerator | '/' | r.denominator;
    173205                } // ?|?
    174206
    175                 void ?|?( ostype & os, Rational(RationalImpl) r ) {
     207                void ?|?( ostype & os, Rational(T) r ) {
    176208                        (ostype &)(os | r); ends( os );
    177209                } // ?|?
     
    179211} // distribution
    180212
    181 forall( RationalImpl | arithmetic( RationalImpl ) | { RationalImpl ?\?( RationalImpl, unsigned long ); } )
    182 Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ) {
    183         if ( y < 0 ) {
    184                 return (Rational(RationalImpl)){ x.denominator \ -y, x.numerator \ -y };
    185         } else {
    186                 return (Rational(RationalImpl)){ x.numerator \ y, x.denominator \ y };
    187         } // if
    188 }
     213forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {
     214        Rational(T) ?\?( Rational(T) x, long int y ) {
     215                if ( y < 0 ) {
     216                        return (Rational(T)){ x.denominator \ -y, x.numerator \ -y };
     217                } else {
     218                        return (Rational(T)){ x.numerator \ y, x.denominator \ y };
     219                } // if
     220        } // ?\?
     221
     222        Rational(T) ?\=?( Rational(T) & x, long int y ) {
     223                return x = x \ y;
     224        } // ?\?
     225} // distribution
    189226
    190227// conversion
    191228
    192 forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
    193 double widen( Rational(RationalImpl) r ) {
     229forall( T | Arithmetic( T ) | { double convert( T ); } )
     230double widen( Rational(T) r ) {
    194231        return convert( r.numerator ) / convert( r.denominator );
    195232} // widen
    196233
    197 forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
    198 Rational(RationalImpl) narrow( double f, RationalImpl md ) {
     234forall( T | Arithmetic( T ) | { double convert( T ); T convert( double ); } )
     235Rational(T) narrow( double f, T md ) {
    199236        // http://www.ics.uci.edu/~eppstein/numth/frap.c
    200         if ( md <= (RationalImpl){1} ) {                                        // maximum fractional digits too small?
    201                 return (Rational(RationalImpl)){ convert( f ), (RationalImpl){1}}; // truncate fraction
     237        if ( md <= (T){1} ) {                                   // maximum fractional digits too small?
     238                return (Rational(T)){ convert( f ), (T){1}}; // truncate fraction
    202239        } // if
    203240
    204241        // continued fraction coefficients
    205         RationalImpl m00 = {1}, m11 = { 1 }, m01 = { 0 }, m10 = { 0 };
    206         RationalImpl ai, t;
     242        T m00 = {1}, m11 = { 1 }, m01 = { 0 }, m10 = { 0 };
     243        T ai, t;
    207244
    208245        // find terms until denom gets too big
     
    221258          if ( f > (double)0x7FFFFFFF ) break;                          // representation failure
    222259        } // for
    223         return (Rational(RationalImpl)){ m00, m10 };
     260        return (Rational(T)){ m00, m10 };
    224261} // narrow
    225262
Note: See TracChangeset for help on using the changeset viewer.