ARPDAS_QNX6 1.0
rational.c
Go to the documentation of this file.
00001 /* rational.c defines the various operations on rational numbers.
00002    Written February 25, 1988
00003    Modified November 20, 1988 not to pass structures.
00004 */
00005 char rcsid_rational_c[] =
00006   "$Header: /cvsroot/arp-das/nortlib2/src/rational.c,v 1.1 2008/07/03 19:46:28 ntallen Exp $";
00007 
00008 #include <limits.h>
00009 #include "rational.h"
00010 #include "nortlib.h"
00011 
00012 rational zero = {0,1};
00013 rational one_half = {1,2};
00014 rational one = {1,1};
00015 
00016 static void lreduce(long int num, long int den, rational *a) {
00017   int sign;
00018   long int r0, r1, r2;
00019 
00020   if (den < 0) { den = -den; num  = -num;}
00021   else if (den == 0) {
00022     a->num = 0;
00023     a->den = 1;
00024     return;
00025   }
00026   if (num < 0) { sign = 1; num = -num;}
00027   else if (num == 0) {
00028         a->num = 0;
00029     a->den = 1;
00030     return;
00031   } else sign = 0;
00032   if (num > den) { r0 = num; r1 = den;}
00033   else { r0 = den; r1 = num;}
00034   for (;;) {
00035     r2 = r0 % r1;
00036     if (r2 == 0) break;
00037     r0 = r1;
00038     r1 = r2;
00039   }
00040   num /= r1;
00041   den /= r1;
00042   if ( num < 0 || den < 0 )
00043         nl_error( 4, "Algorithmic error in rational lreduce" );
00044   if ( num > INT_MAX || den > INT_MAX ) {
00045         int resp;
00046 
00047         if ( nl_response > 2 ) resp = 4;
00048         else if ( nl_response > 0 ) resp = 1;
00049         else resp = 0;
00050         if ( resp )
00051           nl_error( resp,
00052                 "Cannot reduce %ld/%ld to short rational", num, den );
00053         num = 0;
00054         den = 1;
00055   }
00056   if (sign) num = -num;
00057   a->num = num;
00058   a->den = den;
00059   return;
00060 }
00061 
00062 void rreduce(rational *a) {
00063   lreduce((long) a->num, (long) a->den, a);
00064 }
00065 
00066 /* c may be one of a or b */
00067 void rplus(rational *a, rational *b, rational *c) {
00068   lreduce(a->num*(long) b->den + a->den*(long) b->num,
00069                   a->den*(long) b->den, c);
00070 }
00071 
00072 void rminus(rational *a, rational *b, rational *c) {
00073   lreduce(a->num*(long) b->den - a->den*(long) b->num,
00074                   a->den*(long) b->den, c);
00075 }
00076 
00077 void rtimes(rational *a, rational *b, rational *c) {
00078   lreduce(a->num*(long) b->num, a->den*(long) b->den, c);
00079 }
00080 
00081 void rtimesint(rational *a, short int b, rational *c) {
00082   lreduce(a->num * (long) b, (long) a->den, c);
00083 }
00084 
00085 void rdivideint(rational *a, short int b, rational *c) {
00086   lreduce((long) a->num, a->den * (long) b, c);
00087 }
00088 
00089 void rdivide(rational *a, rational *b, rational *c) {
00090   lreduce(a->num * (long) b->den, b->num * (long) a->den, c);
00091 }
00092 
00093 /*+rational
00094 <sort> rcompare
00095 
00096 c = rcompare(a,b);
00097 int c;
00098 rational *a, *b;
00099 rcompare returns -1 if a < b, 0 if a = b, and 1 if a > b.  It assumes both
00100 a and b are in reduced form to the extent that the denominator is positive.
00101 If this is not the case, an incorrect response is virtually assured.
00102 -*/
00103 int rcompare(rational *a, rational *b) {
00104   long int diff;
00105 
00106   diff = a->num * (long) b->den - a->den * (long) b->num;
00107   if (diff == 0) return(0);
00108   else if (diff < 0) return(-1);
00109   return(1);
00110 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines