Optimizations in the dispatch of +,- and new dispatches for * and /

This commit is contained in:
Juan Jose Garcia Ripoll 2010-11-05 23:00:28 +01:00
parent 27a58ecab7
commit 2f3d4a450c
4 changed files with 310 additions and 18 deletions

View file

@ -28,6 +28,155 @@
@(return num)
@)
#if 1
static cl_object
complex_divide(cl_object ar, cl_object ai, cl_object br, cl_object bi)
{
/* #C(z1 z2) = #C(xr xi) * #C(yr -yi) */
cl_object z1 = ecl_plus(ecl_times(ar, br), ecl_times(ai, bi));
cl_object z2 = ecl_minus(ecl_times(ai, br), ecl_times(ar, bi));
cl_object absB = ecl_plus(ecl_times(br, br), ecl_times(bi, bi));
return ecl_make_complex(ecl_divide(z1, absB), ecl_divide(z2, absB));
}
cl_object
ecl_divide(cl_object x, cl_object y)
{
MATH_DISPATCH2_BEGIN(x,y)
{
CASE_FIXNUM_FIXNUM;
CASE_BIGNUM_FIXNUM {
if (y == MAKE_FIXNUM(0))
FEdivision_by_zero(x, y);
}
CASE_FIXNUM_BIGNUM;
CASE_BIGNUM_BIGNUM {
return ecl_make_ratio(x, y);
}
CASE_FIXNUM_RATIO;
CASE_BIGNUM_RATIO {
return ecl_make_ratio(ecl_times(x, y->ratio.den),
y->ratio.num);
}
CASE_FIXNUM_SINGLE_FLOAT {
return ecl_make_singlefloat(fix(x) / ecl_single_float(y));
}
CASE_FIXNUM_DOUBLE_FLOAT {
return ecl_make_doublefloat(fix(x) / ecl_double_float(y));
}
CASE_BIGNUM_SINGLE_FLOAT;
CASE_RATIO_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_to_float(x) / ecl_single_float(y));
}
CASE_BIGNUM_DOUBLE_FLOAT;
CASE_RATIO_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_to_double(x) / ecl_double_float(y));
}
CASE_RATIO_FIXNUM {
if (y == MAKE_FIXNUM(0)) {
FEdivision_by_zero(x,y);
}
}
CASE_RATIO_BIGNUM {
cl_object z = ecl_times(x->ratio.den, y);
return ecl_make_ratio(x->ratio.num, z);
}
CASE_RATIO_RATIO {
cl_object num = ecl_times(x->ratio.num,y->ratio.den);
cl_object den = ecl_times(x->ratio.den,y->ratio.num);
return ecl_make_ratio(num, den);
}
CASE_SINGLE_FLOAT_FIXNUM {
return ecl_make_singlefloat(ecl_single_float(x) / fix(y));
}
CASE_SINGLE_FLOAT_BIGNUM;
CASE_SINGLE_FLOAT_RATIO {
return ecl_make_singlefloat(ecl_single_float(x) / ecl_to_float(y));
}
CASE_SINGLE_FLOAT_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_single_float(x) / ecl_single_float(y));
}
CASE_SINGLE_FLOAT_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_single_float(x) / ecl_double_float(y));
}
CASE_DOUBLE_FLOAT_FIXNUM {
return ecl_make_doublefloat(ecl_double_float(x) / fix(y));
}
CASE_DOUBLE_FLOAT_BIGNUM;
CASE_DOUBLE_FLOAT_RATIO {
return ecl_make_doublefloat(ecl_double_float(x) / ecl_to_double(y));
}
CASE_DOUBLE_FLOAT_SINGLE_FLOAT {
return ecl_make_doublefloat(ecl_double_float(x) / ecl_single_float(y));
}
CASE_DOUBLE_FLOAT_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_double_float(x) / ecl_double_float(y));
}
#ifdef ECL_LONG_FLOAT
CASE_FIXNUM_LONG_FLOAT {
return ecl_make_longfloat(fix(x) / ecl_long_float(y));
}
CASE_BIGNUM_LONG_FLOAT;
CASE_RATIO_LONG_FLOAT {
return ecl_make_longfloat(ecl_to_long_double(x) / ecl_long_float(y));
}
CASE_SINGLE_FLOAT_LONG_FLOAT {
return ecl_make_longfloat(ecl_single_float(x) / ecl_long_float(y));
}
CASE_DOUBLE_FLOAT_LONG_FLOAT {
return ecl_make_longfloat(ecl_double_float(x) / ecl_long_float(y));
}
CASE_LONG_FLOAT_FIXNUM {
return ecl_make_longfloat(ecl_long_float(x) / fix(y));
}
CASE_LONG_FLOAT_BIGNUM;
CASE_LONG_FLOAT_RATIO {
return ecl_make_longfloat(ecl_long_float(x) / ecl_to_long_double(y));
}
CASE_LONG_FLOAT_SINGLE_FLOAT {
return ecl_make_longfloat(ecl_long_float(x) / ecl_single_float(y));
}
CASE_LONG_FLOAT_DOUBLE_FLOAT {
return ecl_make_longfloat(ecl_long_float(x) / ecl_double_float(y));
}
CASE_LONG_FLOAT_LONG_FLOAT {
return ecl_make_longfloat(ecl_long_float(x) / ecl_long_float(y));
}
CASE_LONG_FLOAT_COMPLEX {
goto COMPLEX_Y;
}
CASE_COMPLEX_LONG_FLOAT; {
goto COMPLEX_X;
}
#endif
CASE_COMPLEX_FIXNUM;
CASE_COMPLEX_BIGNUM;
CASE_COMPLEX_RATIO;
CASE_COMPLEX_SINGLE_FLOAT;
CASE_COMPLEX_DOUBLE_FLOAT; COMPLEX_X: {
return ecl_make_complex(ecl_divide(x->complex.real, y),
ecl_divide(x->complex.imag, y));
}
CASE_BIGNUM_COMPLEX;
CASE_RATIO_COMPLEX;
CASE_SINGLE_FLOAT_COMPLEX;
CASE_DOUBLE_FLOAT_COMPLEX;
CASE_FIXNUM_COMPLEX {
COMPLEX_Y:
return complex_divide(x, MAKE_FIXNUM(0), y->complex.real, y->complex.imag);
}
CASE_COMPLEX_COMPLEX {
return complex_divide(x->complex.real, x->complex.imag,
y->complex.real, y->complex.imag);
}
CASE_UNKNOWN(@[/],x,y,@[number]);
}
MATH_DISPATCH2_END;
}
#else
cl_object
ecl_divide(cl_object x, cl_object y)
{
@ -172,3 +321,5 @@ ecl_divide(cl_object x, cl_object y)
FEwrong_type_nth_arg(@[/], 1, x, @[number]);
}
}
#endif

View file

@ -58,10 +58,12 @@ MATH_DISPATCH2_BEGIN(x,y)
CASE_BIGNUM_BIGNUM {
return _ecl_big_minus_big(x, y);
}
CASE_BIGNUM_SINGLE_FLOAT {
CASE_BIGNUM_SINGLE_FLOAT;
CASE_RATIO_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_to_float(x) - ecl_single_float(y));
}
CASE_BIGNUM_DOUBLE_FLOAT {
CASE_BIGNUM_DOUBLE_FLOAT;
CASE_RATIO_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_to_double(x) - ecl_double_float(y));
}
CASE_RATIO_FIXNUM;
@ -77,12 +79,6 @@ MATH_DISPATCH2_BEGIN(x,y)
z1 = ecl_times(x->ratio.den,y->ratio.den);
return ecl_make_ratio(z, z1);
}
CASE_RATIO_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_to_float(x) - ecl_single_float(y));
}
CASE_RATIO_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_to_double(x) - ecl_double_float(y));
}
CASE_SINGLE_FLOAT_FIXNUM {
return ecl_make_singlefloat(ecl_single_float(x) - fix(y));
}
@ -130,7 +126,7 @@ MATH_DISPATCH2_BEGIN(x,y)
}
CASE_LONG_FLOAT_BIGNUM;
CASE_LONG_FLOAT_RATIO {
return ecl_make_longfloat(ecl_long_float(x) - ecl_to_double(y));
return ecl_make_longfloat(ecl_long_float(x) - ecl_to_long_double(y));
}
CASE_LONG_FLOAT_SINGLE_FLOAT {
return ecl_make_longfloat(ecl_long_float(x) - ecl_single_float(y));

View file

@ -56,10 +56,12 @@ MATH_DISPATCH2_BEGIN(x,y)
CASE_BIGNUM_BIGNUM {
return _ecl_big_plus_big(x, y);
}
CASE_BIGNUM_SINGLE_FLOAT {
CASE_BIGNUM_SINGLE_FLOAT;
CASE_RATIO_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_to_float(x) + ecl_single_float(y));
}
CASE_BIGNUM_DOUBLE_FLOAT {
CASE_BIGNUM_DOUBLE_FLOAT;
CASE_RATIO_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_to_double(x) + ecl_double_float(y));
}
CASE_RATIO_FIXNUM;
@ -75,12 +77,6 @@ MATH_DISPATCH2_BEGIN(x,y)
z1 = ecl_times(x->ratio.den,y->ratio.den);
return ecl_make_ratio(z, z1);
}
CASE_RATIO_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_to_float(x) + ecl_single_float(y));
}
CASE_RATIO_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_to_double(x) + ecl_double_float(y));
}
CASE_SINGLE_FLOAT_FIXNUM {
return ecl_make_singlefloat(ecl_single_float(x) + fix(y));
}
@ -128,7 +124,7 @@ MATH_DISPATCH2_BEGIN(x,y)
}
CASE_LONG_FLOAT_BIGNUM;
CASE_LONG_FLOAT_RATIO {
return ecl_make_longfloat(ecl_long_float(x) + ecl_to_double(y));
return ecl_make_longfloat(ecl_long_float(x) + ecl_to_long_double(y));
}
CASE_LONG_FLOAT_SINGLE_FLOAT {
return ecl_make_longfloat(ecl_long_float(x) + ecl_single_float(y));

View file

@ -25,6 +25,153 @@
@(return prod)
@)
#if 1
cl_object
ecl_times(cl_object x, cl_object y)
{
MATH_DISPATCH2_BEGIN(x,y)
{
CASE_FIXNUM_FIXNUM {
return _ecl_fix_times_fix(fix(x), fix(y));
}
CASE_FIXNUM_BIGNUM {
return _ecl_big_times_fix(y, fix(x));
}
CASE_FIXNUM_RATIO;
CASE_BIGNUM_RATIO {
return ecl_make_ratio(ecl_times(x, y->ratio.num),
y->ratio.den);
}
CASE_FIXNUM_SINGLE_FLOAT {
return ecl_make_singlefloat(fix(x) * ecl_single_float(y));
}
CASE_FIXNUM_DOUBLE_FLOAT {
return ecl_make_doublefloat(fix(x) * ecl_double_float(y));
}
CASE_BIGNUM_FIXNUM {
return _ecl_big_times_fix(x, fix(y));
}
CASE_BIGNUM_BIGNUM {
return _ecl_big_times_big(x, y);
}
CASE_BIGNUM_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_to_float(x) * ecl_single_float(y));
}
CASE_BIGNUM_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_to_double(x) * ecl_double_float(y));
}
CASE_RATIO_FIXNUM;
CASE_RATIO_BIGNUM {
cl_object z = ecl_times(x->ratio.num, y);
return ecl_make_ratio(z, x->ratio.den);
}
CASE_RATIO_RATIO {
cl_object num = ecl_times(x->ratio.num,y->ratio.num);
cl_object den = ecl_times(x->ratio.den,y->ratio.den);
return ecl_make_ratio(num, den);
}
CASE_RATIO_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_to_float(x) * ecl_single_float(y));
}
CASE_RATIO_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_to_double(x) * ecl_double_float(y));
}
CASE_SINGLE_FLOAT_FIXNUM {
return ecl_make_singlefloat(ecl_single_float(x) * fix(y));
}
CASE_SINGLE_FLOAT_BIGNUM;
CASE_SINGLE_FLOAT_RATIO {
return ecl_make_singlefloat(ecl_single_float(x) * ecl_to_float(y));
}
CASE_SINGLE_FLOAT_SINGLE_FLOAT {
return ecl_make_singlefloat(ecl_single_float(x) * ecl_single_float(y));
}
CASE_SINGLE_FLOAT_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_single_float(x) * ecl_double_float(y));
}
CASE_DOUBLE_FLOAT_FIXNUM {
return ecl_make_doublefloat(ecl_double_float(x) * fix(y));
}
CASE_DOUBLE_FLOAT_BIGNUM;
CASE_DOUBLE_FLOAT_RATIO {
return ecl_make_doublefloat(ecl_double_float(x) * ecl_to_double(y));
}
CASE_DOUBLE_FLOAT_SINGLE_FLOAT {
return ecl_make_doublefloat(ecl_double_float(x) * ecl_single_float(y));
}
CASE_DOUBLE_FLOAT_DOUBLE_FLOAT {
return ecl_make_doublefloat(ecl_double_float(x) * ecl_double_float(y));
}
#ifdef ECL_LONG_FLOAT
CASE_FIXNUM_LONG_FLOAT {
return ecl_make_longfloat(fix(x) * ecl_long_float(y));
}
CASE_BIGNUM_LONG_FLOAT;
CASE_RATIO_LONG_FLOAT {
return ecl_make_longfloat(ecl_to_long_double(x) * ecl_long_float(y));
}
CASE_SINGLE_FLOAT_LONG_FLOAT {
return ecl_make_longfloat(ecl_single_float(x) * ecl_long_float(y));
}
CASE_DOUBLE_FLOAT_LONG_FLOAT {
return ecl_make_longfloat(ecl_double_float(x) * ecl_long_float(y));
}
CASE_LONG_FLOAT_FIXNUM {
return ecl_make_longfloat(ecl_long_float(x) * fix(y));
}
CASE_LONG_FLOAT_BIGNUM;
CASE_LONG_FLOAT_RATIO {
return ecl_make_longfloat(ecl_long_float(x) * ecl_to_long_double(y));
}
CASE_LONG_FLOAT_SINGLE_FLOAT {
return ecl_make_longfloat(ecl_long_float(x) * ecl_single_float(y));
}
CASE_LONG_FLOAT_DOUBLE_FLOAT {
return ecl_make_longfloat(ecl_long_float(x) * ecl_double_float(y));
}
CASE_LONG_FLOAT_LONG_FLOAT {
return ecl_make_longfloat(ecl_long_float(x) * ecl_long_float(y));
}
CASE_LONG_FLOAT_COMPLEX {
goto COMPLEX_Y;
}
CASE_COMPLEX_LONG_FLOAT; {
goto COMPLEX_X;
}
#endif
CASE_COMPLEX_FIXNUM;
CASE_COMPLEX_BIGNUM;
CASE_COMPLEX_RATIO;
CASE_COMPLEX_SINGLE_FLOAT;
CASE_COMPLEX_DOUBLE_FLOAT; COMPLEX_X: {
cl_object aux = x;
x = y; y = aux;
goto COMPLEX_Y;
}
CASE_BIGNUM_COMPLEX;
CASE_RATIO_COMPLEX;
CASE_SINGLE_FLOAT_COMPLEX;
CASE_DOUBLE_FLOAT_COMPLEX;
CASE_FIXNUM_COMPLEX {
COMPLEX_Y:
return ecl_make_complex(ecl_times(x, y->complex.real),
ecl_times(x, y->complex.imag));
}
CASE_COMPLEX_COMPLEX {
cl_object z11 = ecl_times(x->complex.real, y->complex.real);
cl_object z12 = ecl_times(x->complex.imag, y->complex.imag);
cl_object z21 = ecl_times(x->complex.imag, y->complex.real);
cl_object z22 = ecl_times(x->complex.real, y->complex.imag);
return ecl_make_complex(ecl_minus(z11, z12), ecl_plus(z21, z22));
}
CASE_UNKNOWN(@[*],x,y,@[number]);
}
MATH_DISPATCH2_END;
}
#else
cl_object
ecl_times(cl_object x, cl_object y)
{
@ -185,3 +332,5 @@ ecl_times(cl_object x, cl_object y)
FEwrong_type_nth_arg(@[*], 1, x, @[number]);
}
}
#endif