Ignore:
Timestamp:
Jul 10, 2016, 4:35:32 PM (8 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
4e06c1e, c13d970
Parents:
07bc165
Message:

allow 32-bit compilation of cfa-cpp, and 32-bit compilation of CFA programs (including CFA libraries)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/rational.c

    r07bc165 r6e4b913  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul  5 18:29:12 2016
    13 // Update Count     : 26
     12// Last Modified On : Sat Jul  9 11:18:04 2016
     13// Update Count     : 40
    1414//
    1515
     
    3131// alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
    3232static long int gcd( long int a, long int b ) {
    33     for ( ;; ) {                                                                                // Euclid's algorithm
     33        for ( ;; ) {                                                                            // Euclid's algorithm
    3434                long int r = a % b;
    3535          if ( r == 0 ) break;
    3636                a = b;
    3737                b = r;
    38     } // for
     38        } // for
    3939        return b;
    4040} // gcd
    4141
    4242static long int simplify( long int *n, long int *d ) {
    43     if ( *d == 0 ) {
     43        if ( *d == 0 ) {
    4444                serr | "Invalid rational number construction: denominator cannot be equal to 0." | endl;
    4545                exit( EXIT_FAILURE );
    46     } // exit
    47     if ( *d < 0 ) { *d = -*d; *n = -*n; }                               // move sign to numerator
    48     return gcd( abs( *n ), *d );                                                // simplify
     46        } // exit
     47        if ( *d < 0 ) { *d = -*d; *n = -*n; }                           // move sign to numerator
     48        return gcd( abs( *n ), *d );                                            // simplify
    4949} // Rationalnumber::simplify
    5050
     
    5353
    5454void ?{}( Rational * r ) {
    55     r{ 0, 1 };
     55        r{ 0, 1 };
    5656} // rational
    5757
    5858void ?{}( Rational * r, long int n ) {
    59     r{ n, 1 };
     59        r{ n, 1 };
    6060} // rational
    6161
    6262void ?{}( Rational * r, long int n, long int d ) {
    63     long int t = simplify( &n, &d );                                    // simplify
    64     r->numerator = n / t;
     63        long int t = simplify( &n, &d );                                        // simplify
     64        r->numerator = n / t;
    6565        r->denominator = d / t;
    6666} // rational
     
    7070
    7171long int numerator( Rational r ) {
    72     return r.numerator;
     72        return r.numerator;
    7373} // numerator
    7474
    7575long int numerator( Rational r, long int n ) {
    76     long int prev = r.numerator;
    77     long int t = gcd( abs( n ), r.denominator );                // simplify
    78     r.numerator = n / t;
    79     r.denominator = r.denominator / t;
    80     return prev;
     76        long int prev = r.numerator;
     77        long int t = gcd( abs( n ), r.denominator );            // simplify
     78        r.numerator = n / t;
     79        r.denominator = r.denominator / t;
     80        return prev;
    8181} // numerator
    8282
    8383long int denominator( Rational r ) {
    84     return r.denominator;
     84        return r.denominator;
    8585} // denominator
    8686
    8787long int denominator( Rational r, long int d ) {
    88     long int prev = r.denominator;
    89     long int t = simplify( &r.numerator, &d );                  // simplify
    90     r.numerator = r.numerator / t;
    91     r.denominator = d / t;
    92     return prev;
     88        long int prev = r.denominator;
     89        long int t = simplify( &r.numerator, &d );                      // simplify
     90        r.numerator = r.numerator / t;
     91        r.denominator = d / t;
     92        return prev;
    9393} // denominator
    9494
     
    9797
    9898int ?==?( Rational l, Rational r ) {
    99     return l.numerator * r.denominator == l.denominator * r.numerator;
     99        return l.numerator * r.denominator == l.denominator * r.numerator;
    100100} // ?==?
    101101
    102102int ?!=?( Rational l, Rational r ) {
    103     return ! ( l == r );
     103        return ! ( l == r );
    104104} // ?!=?
    105105
    106106int ?<?( Rational l, Rational r ) {
    107     return l.numerator * r.denominator < l.denominator * r.numerator;
     107        return l.numerator * r.denominator < l.denominator * r.numerator;
    108108} // ?<?
    109109
    110110int ?<=?( Rational l, Rational r ) {
    111     return l < r || l == r;
     111        return l < r || l == r;
    112112} // ?<=?
    113113
    114114int ?>?( Rational l, Rational r ) {
    115     return ! ( l <= r );
     115        return ! ( l <= r );
    116116} // ?>?
    117117
    118118int ?>=?( Rational l, Rational r ) {
    119     return ! ( l < r );
     119        return ! ( l < r );
    120120} // ?>=?
    121121
     
    125125Rational -?( Rational r ) {
    126126        Rational t = { -r.numerator, r.denominator };
    127     return t;
     127        return t;
    128128} // -?
    129129
    130130Rational ?+?( Rational l, Rational r ) {
    131     if ( l.denominator == r.denominator ) {                             // special case
     131        if ( l.denominator == r.denominator ) {                         // special case
    132132                Rational t = { l.numerator + r.numerator, l.denominator };
    133133                return t;
    134     } else {
     134        } else {
    135135                Rational t = { l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
    136136                return t;
    137     } // if
     137        } // if
    138138} // ?+?
    139139
    140140Rational ?-?( Rational l, Rational r ) {
    141     if ( l.denominator == r.denominator ) {                             // special case
     141        if ( l.denominator == r.denominator ) {                         // special case
    142142                Rational t = { l.numerator - r.numerator, l.denominator };
    143143                return t;
    144     } else {
     144        } else {
    145145                Rational t = { l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
    146146                return t;
    147     } // if
     147        } // if
    148148} // ?-?
    149149
    150150Rational ?*?( Rational l, Rational r ) {
    151     Rational t = { l.numerator * r.numerator, l.denominator * r.denominator };
     151        Rational t = { l.numerator * r.numerator, l.denominator * r.denominator };
    152152        return t;
    153153} // ?*?
    154154
    155155Rational ?/?( Rational l, Rational r ) {
    156     if ( r.numerator < 0 ) {
     156        if ( r.numerator < 0 ) {
    157157                r.numerator = -r.numerator;
    158158                r.denominator = -r.denominator;
    159159        } // if
    160160        Rational t = { l.numerator * r.denominator, l.denominator * r.numerator };
    161     return t;
     161        return t;
    162162} // ?/?
    163163
     
    169169} // widen
    170170
    171 // https://rosettacode.org/wiki/Convert_decimal_number_to_rational#C
     171// http://www.ics.uci.edu/~eppstein/numth/frap.c
    172172Rational narrow( double f, long int md ) {
    173173        if ( md <= 1 ) {                                                                        // maximum fractional digits too small?
     
    176176
    177177        // continued fraction coefficients
    178         long int a, h[3] = { 0, 1, 0 }, k[3] = { 1, 0, 0 };
    179         long int x, d, n = 1;
    180         int i, neg = 0;
    181  
    182         if ( f < 0 ) { neg = 1; f = -f; }
    183         while ( f != floor( f ) ) { n <<= 1; f *= 2; }
    184         d = f;
    185  
    186         // continued fraction and check denominator each step
    187         for (i = 0; i < 64; i++) {
    188                 a = n ? d / n : 0;
    189           if (i && !a) break;
    190                 x = d; d = n; n = x % n;
    191                 x = a;
    192                 if (k[1] * a + k[0] >= md) {
    193                         x = (md - k[0]) / k[1];
    194                   if ( ! (x * 2 >= a || k[1] >= md) ) break;
    195                         i = 65;
    196                 } // if
    197                 h[2] = x * h[1] + h[0]; h[0] = h[1]; h[1] = h[2];
    198                 k[2] = x * k[1] + k[0]; k[0] = k[1]; k[1] = k[2];
    199         } // for
    200         return (Rational){ neg ? -h[1] : h[1], k[1] };
     178        long int m00 = 1, m11 = 1, m01 = 0, m10 = 0;
     179        long int ai, t;
     180
     181        // find terms until denom gets too big
     182        for ( ;; ) {
     183                ai = (long int)f;
     184          if ( ! (m10 * ai + m11 <= md) ) break;
     185                t = m00 * ai + m01;
     186                m01 = m00;
     187                m00 = t;
     188                t = m10 * ai + m11;
     189                m11 = m10;
     190                m10 = t;
     191                t = (double)ai;
     192          if ( f == t ) break;                                                          // prevent division by zero
     193                f = 1 / (f - t);
     194          if ( f > (double)0x7FFFFFFF ) break;                          // representation failure
     195        }
     196        return (Rational){ m00, m10 };
    201197} // narrow
    202198
     
    207203istype * ?|?( istype *is, Rational *r ) {
    208204        long int t;
    209     is | &(r->numerator) | &(r->denominator);
     205        is | &(r->numerator) | &(r->denominator);
    210206        t = simplify( &(r->numerator), &(r->denominator) );
    211     r->numerator /= t;
    212     r->denominator /= t;
    213     return is;
     207        r->numerator /= t;
     208        r->denominator /= t;
     209        return is;
    214210} // ?|?
    215211
    216212forall( dtype ostype | ostream( ostype ) )
    217213ostype * ?|?( ostype *os, Rational r ) {
    218     return os | r.numerator | '/' | r.denominator;
     214        return os | r.numerator | '/' | r.denominator;
    219215} // ?|?
    220216
Note: See TracChangeset for help on using the changeset viewer.