// // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // rational -- Rational numbers are numbers written as a ratio, i.e., as a fraction, where the numerator (top number) // and the denominator (bottom number) are whole numbers. When creating and computing with rational numbers, results // are constantly reduced to keep the numerator and denominator as small as possible. // // Author : Peter A. Buhr // Created On : Wed Apr 6 17:56:25 2016 // Last Modified By : Peter A. Buhr // Last Modified On : Wed Dec 6 23:12:53 2017 // Update Count : 97 // #pragma once #include "iostream" trait scalar( otype T ) { }; trait arithmetic( otype T | scalar( T ) ) { int !?( T ); int ?==?( T, T ); int ?!=?( T, T ); int ??( T, T ); int ?>=?( T, T ); void ?{}( T &, zero_t ); void ?{}( T &, one_t ); T +?( T ); T -?( T ); T ?+?( T, T ); T ?-?( T, T ); T ?*?( T, T ); T ?/?( T, T ); T ?%?( T, T ); T ?/=?( T &, T ); T abs( T ); }; // implementation forall( otype RationalImpl | arithmetic( RationalImpl ) ) struct Rational { RationalImpl numerator, denominator; // invariant: denominator > 0 }; // Rational // constructors forall( otype RationalImpl | arithmetic( RationalImpl ) ) void ?{}( Rational(RationalImpl) & r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) void ?{}( Rational(RationalImpl) & r, RationalImpl n ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) void ?{}( Rational(RationalImpl) & r, zero_t ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) void ?{}( Rational(RationalImpl) & r, one_t ); // numerator/denominator getter forall( otype RationalImpl | arithmetic( RationalImpl ) ) RationalImpl numerator( Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) RationalImpl denominator( Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) [ RationalImpl, RationalImpl ] ?=?( & [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ); // numerator/denominator setter forall( otype RationalImpl | arithmetic( RationalImpl ) ) RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ); // comparison forall( otype RationalImpl | arithmetic( RationalImpl ) ) int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) int ??( Rational(RationalImpl) l, Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ); // arithmetic forall( otype RationalImpl | arithmetic( RationalImpl ) ) Rational(RationalImpl) +?( Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) Rational(RationalImpl) -?( Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ); // conversion forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) double widen( Rational(RationalImpl) r ); forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double );} ) Rational(RationalImpl) narrow( double f, RationalImpl md ); // I/O forall( otype RationalImpl | arithmetic( RationalImpl ) ) forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } ) istype & ?|?( istype &, Rational(RationalImpl) & ); forall( otype RationalImpl | arithmetic( RationalImpl ) ) forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) ostype & ?|?( ostype &, Rational(RationalImpl ) ); // Local Variables: // // mode: c // // tab-width: 4 // // End: //