home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_11_04 / 1104074a < prev    next >
Text File  |  1992-12-23  |  3KB  |  134 lines

  1. /* fraction.c */
  2. /* Copyright 1992 by P.J. LaBrocca */
  3.  
  4. #include <stdio.h>
  5. #include "mixed.h"
  6.  
  7. mixed_t *mix_init( mixed_t *m, Integer w, Integer n, Integer d )
  8. {
  9.     m->sign  = POSITIVE;
  10.     m->whole = w;
  11.     if( w < 0 ) {
  12.         m->sign  = NEGATIVE;
  13.         m->whole *= -1;
  14.     }
  15.     m->num   = n;
  16.     m->den   = d;
  17.     m->factors[ NUMER ][ 0 ] = 1;
  18.     m->factors[ DENOM ][ 0 ] = 1;
  19.     return m;
  20. }
  21.  
  22. mixed_t *mix_clear( mixed_t *m )
  23. {
  24.     m->whole = 0;
  25.     m->num   = 0;
  26.     m->den   = 1;
  27.     m->factors[ NUMER ][ 0 ] = 1;
  28.     m->factors[ DENOM ][ 0 ] = 1;
  29.     m->sign  = POSITIVE;
  30.     return m;
  31. }
  32.  
  33. mixed_t *mix_factor( mixed_t *m )
  34. {
  35.     Integer n;
  36.     int i;
  37.     Integer *pi;
  38.     Integer *pp;
  39.  
  40.     for( i = 0; i < 2; ++i) {
  41.         pp = Primes;       /* point to global array of primes */
  42.         (i != 0) ? (n = m->den) : (n = m->num);
  43.         pi = &m->factors[i][0];
  44.  
  45.         while(n > 1) {
  46.             if( !(n % *pp) ) {   /* if there is no remainder */
  47.                 n = (Integer) (n / *pp);  /* factor the prime out of number */
  48.                 *pi = *pp;         /* save the prime */
  49.                 ++pi;
  50.                 continue;         /* try the prime again */
  51.             }
  52.             ++pp;               /* next prime */
  53.         }
  54.         *pi = 1;
  55.         pp = Primes;
  56.     }
  57.     return m;
  58. }
  59.  
  60. mixed_t *mix_reduce( mixed_t *m )
  61. {
  62.     Integer tnum = 1, tden = 1;
  63.     Integer *top = &m->factors[NUMER][0];
  64.     Integer *bot = &m->factors[DENOM][0];
  65.  
  66.     if( m->num == 0) {
  67.         return m;
  68.     }
  69.     if( m->den == 1 ) {
  70.         m->whole += m->num;
  71.         m->num = 0;
  72.         return m;
  73.     }
  74.     mix_factor( m );  /* got to factor to reduce */
  75.                      /*accumulators for reduced numerator & denominator*/
  76.     while(*top != 1 && *bot != 1) {    /* neither factor is sentinel */
  77.             if(*top == *bot) {    /* if the current factors are equal..*/
  78.                     ++top;        /* ..cancel them & continue */
  79.                     ++bot;
  80.                     continue;
  81.             }               /* otherwise accumulate the smaller*/
  82.             (*top < *bot) ? (tnum *= *top++) : (tden *= *bot++);
  83.  
  84.     }
  85.     while(*top != 1)              /* any remaining factors are */
  86.             tnum *= *top++;      /* multiplied in */
  87.     while(*bot != 1)
  88.             tden *= *bot++;
  89.     if(tnum == tden) {    /*ie, n/d == 1*/
  90.         ++m->whole;          /*add 1 to whole*/
  91.         m->num = 0;
  92.         m->den = 1;
  93.     }
  94.     else if(tnum > tden) {              /*improper fraction*/
  95.         m->whole += (Integer) (tnum / tden);
  96.         m->num = tnum % tden;
  97.         m->den = tden;
  98.     }
  99.     else {                              /*proper fraction*/
  100.         m->num = tnum;
  101.         m->den = tden;
  102.     }
  103.     if(m->num == 0) {          /* keep zero-valued fractions*/
  104.         m->den = 1;            /* in consistent state*/
  105.         if(m->whole == 0)
  106.             mix_clear( m );
  107.     }
  108.     return m;
  109. }
  110.  
  111. void mix_make_improper( mixed_t *m )  /* converts invoking instance*/
  112. {                                   /* into an improper fraction*/
  113.     m->num += m->whole * m->den;             /* if possible*/
  114.     m->whole = 0;
  115. }
  116.  
  117. /* If sizeof( Integer ) changes
  118.    change %ld
  119. */
  120. void mix_print( mixed_t *m )
  121. {
  122.     printf("\t");
  123.     if( m->sign == -1 )
  124.         printf("-");
  125.     if( m->whole != 0 )
  126.         printf("%ld", m->whole);
  127.     if( m->num != 0 )
  128.         printf(" %ld|%ld",m->num, m->den);
  129.     if( (m->whole == 0) && (m->num == 0) )
  130.         printf("0");
  131.     printf("\n");
  132. }
  133.  
  134.