Listing 4 fraction.c - functions for manipulating mixed_ts

/* fraction.c */
/* Copyright 1992 by P.J. LaBrocca */

#include <stdio.h>
#include "mixed.h"

mixed_t *mix_init( mixed_t *m, Integer w, Integer n, Integer d )
{
    m->sign  = POSITIVE;
    m->whole = w;
    if( w < 0) {
       m->sign = NEGATIVE;
       m->whole *= -1;
    }
    m->num  = n;
    m->den  = d;
    m->factors[ NUMER ][ 0 ] = 1;
    m->factors[ DENOM ][ 0 ] = 1;
    return m;
}

mixed_t *mix_clear( mixed_t *m )
{
    m->whole = 0;
    m->num = 0;
    m->den = 1;
    m->factors [ NUMER ][ 0 ] = 1;
    m->factors [ DENOM ][ 0 ] = 1;
    m->sign = POSITIVE;
    return m;
}

mixed_t *mix_factor( mixed_t *m )
{
    Integer n;
    int i;
    Integer *pi;
    Integer *pp;

    for( i = 0; i < 2; ++i) {
       pp = Primes;  /* point to global array of primes */
       (i != 0) ? (n = m->den) : (n = m->num);
       pi = &m->factors[i][0];

       while(n > 1) {
          if( !(n % *pp) ) {  /* if there is no remainder */
             n = (Integer) (n / *pp); /* factor the prime out of number */
             *pi = *pp;         /* save the prime */
             ++pi;
             continue;        /* try the prime again */
          }
          ++pp;              /* next prime */
       }
       *pi = 1;
       pp = Primes;
    }
    return m;
}

mixed_t *mix_reduce( mixed_t *m )
{
    Integer tnum = 1, tden = 1;
    Integer *top = &m->factors[NUMER][0];
    Integer *bot = &m->factors[DENOM][0];

    if( m->num == 0) {
       return m;
    }
    if( m->den == 1 ) {
       m->whole += m->num;
       m->num = 0;
       return m;
    }
    mix_factor( m ); /* got to factor to reduce */
                 /*accumulators for reduced numerator & denominator*/
    while(*top != 1 && *bot != 1) {  /* neither factor is sentinel */
          if(*top == *bot) {  /* if the current factors are equal..*/
                 ++top;      /* ..cancel them & continue */
                 ++bot;
                 continue;
          }                  /* otherwise accumulate the smaller*/
          (*top < *bot) ? (tnum *= *top++) : (tden *= *bot++);

    }
    while(*top != 1)          /* any remaining factors are */
           tnum *= *top++;  /* multiplied in */
    while(*bot != 1)
           tden *= *bot++;
    if(tnum == tden) {    /*ie, n/d == 1*/
       ++m->whole;          /*add 1 to whole*/
       m->num = 0;
       m->den = 1;
    }
    else if(tnum > tden) {              /*improper fraction*/
       m->whole += (Integer) (tnum / tden);
       m->num = tnum % tden;
       m->den = tden;
    }
    else {                              /*proper fraction*/
       m->num == tnum;
       m->den = tden;
    }
    if(m->num == 0) {                   /* keep zero-valued fractions*/
       m->den = 1;                     /* in consistent state*/
       if(m->whole == 0)
          mix_clear( m );
    }
    return m;
}

void mix_make_improper( mixed_t *m )  /* converts invoking instance*/
{                                   /* into an improper fraction*/
    m->num += m->whole * m->den;            /* if possible*/
    m->whole = 0;
}

/* If sizeof( Integer ) changes
   change %ld
*/
void mix_print( mixed_t *m )
{
    printf("\t");
    if( m->sign == -1 )
       printf("-");
    if( m->whole != 0 )
       printf("%ld", m->whole);
    if( m->num != 0 )
       printf(" %ld|%ld",m->num, m->den);
    if( (m->whole == 0) && (m->num == 0) )
       printf("0");
    printf("\n");
}

/* End of File */