ARPDAS_QNX6 1.0
|
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 }