Changeset 6c6455f


Ignore:
Timestamp:
May 15, 2017, 10:08:23 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
22634b2
Parents:
9ebd778
Message:

second attempt at generic rational type with conversions to/from floating point

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/rational

    r9ebd778 r6c6455f  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Sun May 14 16:49:13 2017
    15 // Update Count     : 78
     14// Last Modified On : Mon May 15 21:30:12 2017
     15// Update Count     : 90
    1616//
    1717
     
    128128
    129129// conversion
    130 // forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    131 // double widen( Rational(RationalImpl) r );
    132 // forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    133 // Rational(RationalImpl) narrow( double f, RationalImpl md );
     130forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     131double widen( Rational(RationalImpl) r );
     132forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl );  RationalImpl convert( double );} )
     133Rational(RationalImpl) narrow( double f, RationalImpl md );
    134134
    135135// I/O
  • src/libcfa/rational.c

    r9ebd778 r6c6455f  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 14 17:25:19 2017
    13 // Update Count     : 131
     12// Last Modified On : Mon May 15 21:29:23 2017
     13// Update Count     : 149
    1414//
    1515
     
    190190// conversion
    191191
    192 // forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    193 // double widen( Rational(RationalImpl) r ) {
    194 //      return (double)r.numerator / (double)r.denominator;
    195 // } // widen
    196 
    197 // // http://www.ics.uci.edu/~eppstein/numth/frap.c
    198 // forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    199 // Rational(RationalImpl) narrow( double f, RationalImpl md ) {
    200 //      if ( md <= 1 ) {                                                                        // maximum fractional digits too small?
    201 //              return (Rational(RationalImpl)){ f, 1};                 // truncate fraction
    202 //      } // if
    203 
    204 //      // continued fraction coefficients
    205 //      RationalImpl m00 = 1, m11 = 1, m01 = 0, m10 = 0;
    206 //      RationalImpl ai, t;
    207 
    208 //      // find terms until denom gets too big
    209 //      for ( ;; ) {
    210 //              ai = (RationalImpl)f;
    211 //        if ( ! (m10 * ai + m11 <= md) ) break;
    212 //              t = m00 * ai + m01;
    213 //              m01 = m00;
    214 //              m00 = t;
    215 //              t = m10 * ai + m11;
    216 //              m11 = m10;
    217 //              m10 = t;
    218 //              t = (double)ai;
    219 //        if ( f == t ) break;                                                          // prevent division by zero
    220 //        f = 1 / (f - (double)t);
    221 //        if ( f > (double)0x7FFFFFFF ) break;                          // representation failure
    222 //      }
    223 //      return (Rational(RationalImpl)){ m00, m10 };
    224 // } // narrow
     192forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     193double widen( Rational(RationalImpl) r ) {
     194        return convert( r.numerator ) / convert( r.denominator );
     195} // widen
     196
     197// http://www.ics.uci.edu/~eppstein/numth/frap.c
     198forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
     199Rational(RationalImpl) narrow( double f, RationalImpl md ) {
     200        if ( md <= (RationalImpl){1} ) {                                        // maximum fractional digits too small?
     201                return (Rational(RationalImpl)){ convert( f ), (RationalImpl){1}}; // truncate fraction
     202        } // if
     203
     204        // continued fraction coefficients
     205        RationalImpl m00 = {1}, m11 = { 1 }, m01 = { 0 }, m10 = { 0 };
     206        RationalImpl ai, t;
     207
     208        // find terms until denom gets too big
     209        for ( ;; ) {
     210                ai = convert( f );
     211          if ( ! (m10 * ai + m11 <= md) ) break;
     212                t = m00 * ai + m01;
     213                m01 = m00;
     214                m00 = t;
     215                t = m10 * ai + m11;
     216                m11 = m10;
     217                m10 = t;
     218                double temp = convert( ai );
     219          if ( f == temp ) break;                                                       // prevent division by zero
     220                f = 1 / (f - temp);
     221          if ( f > (double)0x7FFFFFFF ) break;                          // representation failure
     222        } // for
     223        return (Rational(RationalImpl)){ m00, m10 };
     224} // narrow
    225225
    226226
  • src/tests/.expect/rational.txt

    r9ebd778 r6c6455f  
    17173/1
    18184/3
     19conversion
     200.75
     210.142857142857143
     223.14159292035398
     233/4
     241/7
     25355/113
    1926decompose
    2027more tests
  • src/tests/rational.c

    r9ebd778 r6c6455f  
    1010// Created On       : Mon Mar 28 08:43:12 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 14 18:10:28 2017
    13 // Update Count     : 57
     12// Last Modified On : Mon May 15 21:32:22 2017
     13// Update Count     : 64
    1414//
    1515
     
    2323void ?{}( int * this, zero_t ) { *this = 0; }
    2424void ?{}( int * this, one_t ) { *this = 1; }
     25double convert( int i ) { return (double)i; }
     26int convert( double d ) { return (int)d; }
    2527
    2628int main() {
     
    5759        sout | a / b | endl;
    5860
    59 //      sout | "conversion" | endl;
    60 //      a = (Rational(int)){ 3, 4 };
    61 //      sout | widen( a ) | endl;
    62 //      a = (Rational(int)){ 1, 7 };
    63 //      sout | widen( a ) | endl;
    64 //      a = (Rational(int)){ 355, 113 };
    65 //      sout | widen( a ) | endl;
    66 //      sout | narrow( 0.75, 4 ) | endl;
    67 //      sout | narrow( 0.14285714285714, 16 ) | endl;
    68 //      sout | narrow( 3.14159265358979, 256 ) | endl;
     61        sout | "conversion" | endl;
     62        a = (Rational(int)){ 3, 4 };
     63        sout | widen( a ) | endl;
     64        a = (Rational(int)){ 1, 7 };
     65        sout | widen( a ) | endl;
     66        a = (Rational(int)){ 355, 113 };
     67        sout | widen( a ) | endl;
     68        sout | narrow( 0.75, 4 ) | endl;
     69        sout | narrow( 0.14285714285714, 16 ) | endl;
     70        sout | narrow( 3.14159265358979, 256 ) | endl;
    6971
    7072        sout | "decompose" | endl;
Note: See TracChangeset for help on using the changeset viewer.