Index: src/libcfa/rational
===================================================================
--- src/libcfa/rational	(revision c07d7244c852beffdb4d4bf72171c90c9b7824e9)
+++ src/libcfa/rational	(revision f621a148a747ee2f6841e0a8767c6a3c5fdc51a1)
@@ -12,7 +12,8 @@
 // Created On       : Wed Apr  6 17:56:25 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May  4 14:11:45 2016
-// Update Count     : 16
+// Last Modified On : Mon May  1 08:25:06 2017
+// Update Count     : 33
 //
+
 #ifndef RATIONAL_H
 #define RATIONAL_H
@@ -21,6 +22,7 @@
 
 // implementation
+typedef long int RationalImpl;
 struct Rational {
-	long int numerator, denominator;					// invariant: denominator > 0
+	RationalImpl numerator, denominator;					// invariant: denominator > 0
 }; // Rational
 
@@ -31,12 +33,14 @@
 // constructors
 void ?{}( Rational * r );
-void ?{}( Rational * r, long int n );
-void ?{}( Rational * r, long int n, long int d );
+void ?{}( Rational * r, RationalImpl n );
+void ?{}( Rational * r, RationalImpl n, RationalImpl d );
 
-// getter/setter for numerator/denominator
-long int numerator( Rational r );
-long int numerator( Rational r, long int n );
-long int denominator( Rational r );
-long int denominator( Rational r, long int d );
+// getter for numerator/denominator
+RationalImpl numerator( Rational r );
+RationalImpl denominator( Rational r );
+[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src );
+// setter for numerator/denominator
+RationalImpl numerator( Rational r, RationalImpl n );
+RationalImpl denominator( Rational r, RationalImpl d );
 
 // comparison
@@ -57,5 +61,5 @@
 // conversion
 double widen( Rational r );
-Rational narrow( double f, long int md );
+Rational narrow( double f, RationalImpl md );
 
 // I/O
Index: src/libcfa/rational.c
===================================================================
--- src/libcfa/rational.c	(revision c07d7244c852beffdb4d4bf72171c90c9b7824e9)
+++ src/libcfa/rational.c	(revision f621a148a747ee2f6841e0a8767c6a3c5fdc51a1)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr  6 17:54:28 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul  9 11:18:04 2016
-// Update Count     : 40
+// Last Modified On : Thu Apr 27 17:05:06 2017
+// Update Count     : 51
 // 
 
@@ -30,7 +30,7 @@
 // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals.
 // alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
-static long int gcd( long int a, long int b ) {
+static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
 	for ( ;; ) {										// Euclid's algorithm
-		long int r = a % b;
+		RationalImpl r = a % b;
 	  if ( r == 0 ) break;
 		a = b;
@@ -40,5 +40,5 @@
 } // gcd
 
-static long int simplify( long int *n, long int *d ) {
+static RationalImpl simplify( RationalImpl *n, RationalImpl *d ) {
 	if ( *d == 0 ) {
 		serr | "Invalid rational number construction: denominator cannot be equal to 0." | endl;
@@ -56,10 +56,10 @@
 } // rational
 
-void ?{}( Rational * r, long int n ) {
+void ?{}( Rational * r, RationalImpl n ) {
 	r{ n, 1 };
 } // rational
 
-void ?{}( Rational * r, long int n, long int d ) {
-	long int t = simplify( &n, &d );					// simplify
+void ?{}( Rational * r, RationalImpl n, RationalImpl d ) {
+	RationalImpl t = simplify( &n, &d );				// simplify
 	r->numerator = n / t;
 	r->denominator = d / t;
@@ -67,13 +67,23 @@
 
 
-// getter/setter for numerator/denominator
-
-long int numerator( Rational r ) {
+// getter for numerator/denominator
+
+RationalImpl numerator( Rational r ) {
 	return r.numerator;
 } // numerator
 
-long int numerator( Rational r, long int n ) {
-	long int prev = r.numerator;
-	long int t = gcd( abs( n ), r.denominator );		// simplify
+RationalImpl denominator( Rational r ) {
+	return r.denominator;
+} // denominator
+
+[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src ) {
+	return *dest = src.[ numerator, denominator ];
+}
+
+// setter for numerator/denominator
+
+RationalImpl numerator( Rational r, RationalImpl n ) {
+	RationalImpl prev = r.numerator;
+	RationalImpl t = gcd( abs( n ), r.denominator );		// simplify
 	r.numerator = n / t;
 	r.denominator = r.denominator / t;
@@ -81,11 +91,7 @@
 } // numerator
 
-long int denominator( Rational r ) {
-	return r.denominator;
-} // denominator
-
-long int denominator( Rational r, long int d ) {
-	long int prev = r.denominator;
-	long int t = simplify( &r.numerator, &d );			// simplify
+RationalImpl denominator( Rational r, RationalImpl d ) {
+	RationalImpl prev = r.denominator;
+	RationalImpl t = simplify( &r.numerator, &d );			// simplify
 	r.numerator = r.numerator / t;
 	r.denominator = d / t;
@@ -170,5 +176,5 @@
 
 // http://www.ics.uci.edu/~eppstein/numth/frap.c
-Rational narrow( double f, long int md ) {
+Rational narrow( double f, RationalImpl md ) {
 	if ( md <= 1 ) {									// maximum fractional digits too small?
 		return (Rational){ f, 1};						// truncate fraction
@@ -176,10 +182,10 @@
 
 	// continued fraction coefficients
-	long int m00 = 1, m11 = 1, m01 = 0, m10 = 0;
-	long int ai, t;
+	RationalImpl m00 = 1, m11 = 1, m01 = 0, m10 = 0;
+	RationalImpl ai, t;
 
 	// find terms until denom gets too big
 	for ( ;; ) {
-		ai = (long int)f;
+		ai = (RationalImpl)f;
 	  if ( ! (m10 * ai + m11 <= md) ) break;
 		t = m00 * ai + m01;
@@ -202,5 +208,5 @@
 forall( dtype istype | istream( istype ) )
 istype * ?|?( istype *is, Rational *r ) {
-	long int t;
+	RationalImpl t;
 	is | &(r->numerator) | &(r->denominator);
 	t = simplify( &(r->numerator), &(r->denominator) );
Index: src/tests/.expect/rational.txt
===================================================================
--- src/tests/.expect/rational.txt	(revision f621a148a747ee2f6841e0a8767c6a3c5fdc51a1)
+++ src/tests/.expect/rational.txt	(revision f621a148a747ee2f6841e0a8767c6a3c5fdc51a1)
@@ -0,0 +1,37 @@
+constructor
+3/1 4/1 0/1
+1/2 5/7
+2/3 -3/2
+-2/3 3/2
+logical
+-2/1 -3/2
+1
+1
+1
+0
+0
+arithmetic
+-2/1 -3/2
+-7/2
+-1/2
+3/1
+4/3
+conversion
+0.75
+0.142857142857143
+3.14159292035398
+3/4
+1/7
+355/113
+decompose
+355/113 0 9
+more tests
+-3/2
+0
+1/2 1 1/2
+2/1 1 2/1
+0/1
+1/2 1 1/2
+2/2147483647
+5/2147483647
+2/3 4/5
Index: src/tests/.in/rational.txt
===================================================================
--- src/tests/.in/rational.txt	(revision f621a148a747ee2f6841e0a8767c6a3c5fdc51a1)
+++ src/tests/.in/rational.txt	(revision f621a148a747ee2f6841e0a8767c6a3c5fdc51a1)
@@ -0,0 +1,1 @@
+2 3 4 5
Index: src/tests/rational.c
===================================================================
--- src/tests/rational.c	(revision c07d7244c852beffdb4d4bf72171c90c9b7824e9)
+++ src/tests/rational.c	(revision f621a148a747ee2f6841e0a8767c6a3c5fdc51a1)
@@ -10,6 +10,6 @@
 // Created On       : Mon Mar 28 08:43:12 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul  5 18:29:37 2016
-// Update Count     : 25
+// Last Modified On : Thu Apr 27 17:05:19 2017
+// Update Count     : 40
 // 
 
@@ -36,5 +36,5 @@
 	b = (Rational){ -3, 2 };
 	sout | a | b | endl;
-	sout | a == 1 | endl;
+//	sout | a == 1 | endl; // FIX ME
 	sout | a != b | endl;
 	sout | a <  b | endl;
@@ -61,4 +61,10 @@
 	sout | narrow( 3.14159265358979, 256 ) | endl;
 
+	sout | "decompose" | endl;
+	RationalImpl n, d;
+	[n, d] = a;
+	sout | a | n | d | endl;
+
+	sout | "more tests" | endl;
 	Rational x = { 1, 2 }, y = { 2 };
 	sout | x - y | endl;
