Listing 7 mix_num2.c — functions for doing arithmetic with mixed numbers

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

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

mixed_t mix_sub(mixed_t *x, mixed_t *y)
{
    mixed_t sum, xt, yt;

    mix_clear( &sum );
    mix_make_improper(x);
    mix_make_improper(y);

    xt.num = x->num * y->den;
    xt.den = x->den * y->den;
    yt.num = y->num * x->den;
    yt.den = y->den * x->den;

    sum.num = x->sign * xt.num - y->sign * yt.num;

    if(sum.num < 0) {
       sum.num = labs(sum.num);
       sum.sign = NEGATIVE;
    }
    sum.den = xt.den;  /*xt.den == yt.den at this point*/
    if(sum.num == 0) {
       sum.den = 1;
       if(sum.whole == 0)
          sum.sign = POSITIVE;
    }
    return sum;
}

mixed_t mix_add(mixed_t *x, mixed_t *y)
{
    mixed_t sum, t, xt, yt;

    mix_clear( &sum );

    mix_make_improper(x);
    mix_make_improper(y);

    xt.num = x->num * y->den;
    xt.den = x->den * y->den;
    yt.num = y->num * x->den;
    yt.den = y->den * x->den;

    sum.num = x->sign * xt.num + y->sign * yt.num;

    if(sum.num < 0) {
       sum.num = labs(sum.num);
       sum.sign = NEGATIVE;
    }
    sum.den = xt.den;    /*xt.den == yt.den at this point*/

    if(sum.num == 0) {
       sum.den = 1;
       if(sum.whole == 0)
          sum.sign = POSITIVE;
    }
    return sum;
}

mixed_t mix_mul(mixed_t *x, mixed_t *y)
{
    mixed_t product;
    Integer xn, yn;

    mix_clear( &product );

    xn = x->sign * (x->whole * x->den + x->num);
    yn = y->sign * (y->whole * y->den + y->num);

    product.num = xn * yn;
    product.den = x->den * y->den;
    if(product.num < 0) {
       product.num = labs(product.num);
       product.sign = NEGATIVE;
    }
    if(product.num == 0) {
       product.den = 1;
       if(product.whole == 0)
          product.sign = POSITIVE;
    }
    return product;
}

mixed_t mix_recip(mixed_t f) /*reciprocal*/
{                       /* does not alter f*/
    Integer tmp;
    
    mix_make_improper( &f );
    if(f.num == 0) {
       mix_error("denominator will become zero");
       return f;
    }
    
    tmp= f.num;
    f.num = f.den;
    f.den = tmp;
    return f;
}

mixed_t mix_divide(mixed_t *f, mixed_t *g)
{
    mixed_t rec = mix_recip( *g );
    
    return mix_mul( f, &rec );
}

Integer mix_lcd(mixed_t *f, mixed_t *g)
{
    int i = 0, j = 0;
    Integer low[30];
    Integer *l = low;
    Integer t;

    mix_factor(g);
    mix_factor(f);
    white(1) {
       if(f->factors[1][i] == 1) {
          while(g->factors[1][j] != 1)
            *l++ = g->factors[1][j]++];
          break;
       }
       else if(g->factors[1][j] == 1) {
          while(f->factors[1][i] != 1)
            *l++ = f->factors[1][i++];
          break;
       }
       else if(f->factors[1][i] == g->factors[1][j]) {
          *l++ = f->factors[1][i];
          ++i;
          ++j;
       }
       else if(f->factors[1][i] > g->factors[1][j]) {
          *l++ = g->factors[1][j];
          ++j;
       }
       else if(f->factors[1][i] < g->factors[1][j]) {
          *1++ = f->factors[1][i];
          ++i;
       }
    }
    *l = 1;
    t = 1;
    i = 0;

    while(low[i] !=1)
       t *= low[i++];
    Return t;
}

void mix_neg(mixed_t *f)
{
    if(f->sign == NEGATIVE)
       f->sign = POSITIVE;
    else
       f->sign = NEGATIVE;
}
/* End of File */