factor/native/ratio.c

136 lines
2.9 KiB
C
Raw Normal View History

2004-08-04 22:43:58 -04:00
#include "factor.h"
RATIO* ratio(CELL numerator, CELL denominator)
{
2004-08-05 20:29:52 -04:00
RATIO* ratio = allot(sizeof(RATIO));
2004-08-04 22:43:58 -04:00
ratio->numerator = numerator;
ratio->denominator = denominator;
return ratio;
}
void primitive_ratiop(void)
{
check_non_empty(env.dt);
env.dt = tag_boolean(typep(RATIO_TYPE,env.dt));
}
void primitive_numerator(void)
{
switch(type_of(env.dt))
{
case FIXNUM_TYPE:
case BIGNUM_TYPE:
/* No op */
break;
case RATIO_TYPE:
env.dt = untag_ratio(env.dt)->numerator;
break;
default:
2004-08-05 20:29:52 -04:00
type_error(RATIONAL_TYPE,env.dt);
2004-08-04 22:43:58 -04:00
break;
}
}
void primitive_denominator(void)
{
switch(type_of(env.dt))
{
case FIXNUM_TYPE:
case BIGNUM_TYPE:
env.dt = tag_fixnum(1);
break;
case RATIO_TYPE:
env.dt = untag_ratio(env.dt)->denominator;
break;
default:
2004-08-05 20:29:52 -04:00
type_error(RATIONAL_TYPE,env.dt);
2004-08-04 22:43:58 -04:00
break;
}
}
2004-08-05 15:18:31 -04:00
CELL number_eq_ratio(CELL x, CELL y)
{
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return tag_boolean(
untag_boolean(number_eq(rx->numerator,ry->numerator)) &&
untag_boolean(number_eq(rx->denominator,ry->denominator)));
}
CELL add_ratio(CELL x, CELL y)
{
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return divide(add(multiply(rx->numerator,ry->denominator),
multiply(rx->denominator,ry->numerator)),
multiply(rx->denominator,ry->denominator));
}
CELL subtract_ratio(CELL x, CELL y)
{
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return divide(subtract(multiply(rx->numerator,ry->denominator),
multiply(rx->denominator,ry->numerator)),
multiply(rx->denominator,ry->denominator));
}
CELL multiply_ratio(CELL x, CELL y)
{
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return divide(
multiply(rx->numerator,ry->numerator),
multiply(rx->denominator,ry->denominator));
}
CELL divide_ratio(CELL x, CELL y)
{
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return divide(
multiply(rx->numerator,ry->denominator),
multiply(rx->denominator,ry->numerator));
}
2004-08-05 16:49:55 -04:00
CELL divfloat_ratio(CELL x, CELL y)
{
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return divfloat(
multiply(rx->numerator,ry->denominator),
multiply(rx->denominator,ry->numerator));
}
2004-08-05 15:18:31 -04:00
CELL less_ratio(CELL x, CELL y)
{
2004-08-05 16:49:55 -04:00
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return less(multiply(rx->numerator,ry->denominator),
multiply(ry->numerator,rx->denominator));
2004-08-05 15:18:31 -04:00
}
CELL lesseq_ratio(CELL x, CELL y)
{
2004-08-05 16:49:55 -04:00
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return lesseq(multiply(rx->numerator,ry->denominator),
multiply(ry->numerator,rx->denominator));
2004-08-05 15:18:31 -04:00
}
CELL greater_ratio(CELL x, CELL y)
{
2004-08-05 16:49:55 -04:00
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return greater(multiply(rx->numerator,ry->denominator),
multiply(ry->numerator,rx->denominator));
2004-08-05 15:18:31 -04:00
}
CELL greatereq_ratio(CELL x, CELL y)
{
2004-08-05 16:49:55 -04:00
RATIO* rx = (RATIO*)UNTAG(x);
RATIO* ry = (RATIO*)UNTAG(y);
return greatereq(multiply(rx->numerator,ry->denominator),
multiply(ry->numerator,rx->denominator));
2004-08-05 15:18:31 -04:00
}