diff --git a/src/c/numbers/abs.d b/src/c/numbers/abs.d index 4f938c462..454142000 100644 --- a/src/c/numbers/abs.d +++ b/src/c/numbers/abs.d @@ -15,6 +15,7 @@ See file '../Copyright' for full details. */ +#include #define ECL_INCLUDE_MATH_H #include #include @@ -26,10 +27,23 @@ cl_abs(cl_object x) @(return ecl_abs(x)); } +static cl_object +ecl_abs_fixnum(cl_object x) +{ + return ecl_fixnum_minusp(x)? ecl_make_integer(-fix(x)) : x; +} + +static cl_object +ecl_abs_bignum(cl_object x) +{ + return (_ecl_big_sign(x) < 0)? _ecl_big_negate(x) : x; +} + static cl_object ecl_abs_rational(cl_object x) { - return (ecl_minusp(x))? ecl_negate(x) : x; + return (ecl_minusp(x->ratio.num))? + ecl_make_ratio(ecl_negate(x->ratio.num), x->ratio.den) : x; } static cl_object @@ -80,6 +94,6 @@ ecl_abs_complex(cl_object x) } MATH_DEF_DISPATCH1(abs, @[abs], @[number], - ecl_abs_rational, ecl_abs_single_float, - ecl_abs_double_float, ecl_abs_long_float, + ecl_abs_fixnum, ecl_abs_bignum, ecl_abs_rational, + ecl_abs_single_float, ecl_abs_double_float, ecl_abs_long_float, ecl_abs_complex); diff --git a/src/c/numbers/cos.d b/src/c/numbers/cos.d index 36449565f..c1cf49f93 100644 --- a/src/c/numbers/cos.d +++ b/src/c/numbers/cos.d @@ -68,6 +68,6 @@ ecl_cos_complex(cl_object x) } MATH_DEF_DISPATCH1(cos, @[cos], @[number], - ecl_cos_rational, ecl_cos_single_float, - ecl_cos_double_float, ecl_cos_long_float, + ecl_cos_rational, ecl_cos_rational, ecl_cos_rational, + ecl_cos_single_float, ecl_cos_double_float, ecl_cos_long_float, ecl_cos_complex); diff --git a/src/c/numbers/cosh.d b/src/c/numbers/cosh.d index b5c631a1d..a5f759ad5 100644 --- a/src/c/numbers/cosh.d +++ b/src/c/numbers/cosh.d @@ -71,6 +71,6 @@ ecl_cosh_complex(cl_object x) } MATH_DEF_DISPATCH1(cosh, @[cosh], @[number], - ecl_cosh_rational, ecl_cosh_single_float, - ecl_cosh_double_float, ecl_cosh_long_float, + ecl_cosh_rational, ecl_cosh_rational, ecl_cosh_rational, + ecl_cosh_single_float, ecl_cosh_double_float, ecl_cosh_long_float, ecl_cosh_complex); diff --git a/src/c/numbers/exp.d b/src/c/numbers/exp.d index 50f431c2b..afb4905d2 100644 --- a/src/c/numbers/exp.d +++ b/src/c/numbers/exp.d @@ -67,6 +67,6 @@ ecl_exp_complex(cl_object x) } MATH_DEF_DISPATCH1(exp, @[exp], @[number], - ecl_exp_rational, ecl_exp_single_float, - ecl_exp_double_float, ecl_exp_long_float, + ecl_exp_rational, ecl_exp_rational, ecl_exp_rational, + ecl_exp_single_float, ecl_exp_double_float, ecl_exp_long_float, ecl_exp_complex); diff --git a/src/c/numbers/log.d b/src/c/numbers/log.d index 346e1a10b..a70728280 100644 --- a/src/c/numbers/log.d +++ b/src/c/numbers/log.d @@ -50,23 +50,25 @@ ecl_log1_complex_inner(cl_object r, cl_object i) return ecl_make_complex(a, p); } +static cl_object +ecl_log1_bignum(cl_object x) +{ + if (ecl_minusp(x)) { + return ecl_log1_complex_inner(x, MAKE_FIXNUM(0)); + } else { + cl_fixnum l = ecl_integer_length(x) - 1; + cl_object r = ecl_make_ratio(x, ecl_ash(MAKE_FIXNUM(1), l)); + float d = logf(number_to_float(r)) + l * logf(2.0); + return ecl_make_singlefloat(d); + } +} + static cl_object ecl_log1_rational(cl_object x) { - if (type_of(x) == t_bignum) { - if (ecl_minusp(x)) { - return ecl_log1_complex_inner(x, MAKE_FIXNUM(0)); - } else { - cl_fixnum l = ecl_integer_length(x) - 1; - cl_object r = ecl_make_ratio(x, ecl_ash(MAKE_FIXNUM(1), l)); - float d = logf(number_to_float(r)) + l * logf(2.0); - return ecl_make_singlefloat(d); - } - } else { - float f = number_to_float(x); - if (f < 0) return ecl_log1_complex_inner(x, MAKE_FIXNUM(0)); - return ecl_make_singlefloat(logf(number_to_float(x))); - } + float f = number_to_float(x); + if (f < 0) return ecl_log1_complex_inner(x, MAKE_FIXNUM(0)); + return ecl_make_singlefloat(logf(number_to_float(x))); } static cl_object @@ -105,8 +107,8 @@ ecl_log1_complex(cl_object x) } MATH_DEF_DISPATCH1(log1, @[log], @[number], - ecl_log1_rational, ecl_log1_single_float, - ecl_log1_double_float, ecl_log1_long_float, + ecl_log1_rational, ecl_log1_bignum, ecl_log1_rational, + ecl_log1_single_float, ecl_log1_double_float, ecl_log1_long_float, ecl_log1_complex); cl_object @@ -177,13 +179,9 @@ ecl_log1p_simple(cl_object x) static cl_object ecl_log1p_rational(cl_object x) { - if (type_of(x) == t_bignum) { - return ecl_log1p_simple(x); - } else { - float f = number_to_float(x); - if (f < -1) return ecl_log1p_simple(x); - return ecl_make_singlefloat(log1pf(number_to_float(x))); - } + float f = number_to_float(x); + if (f < -1) return ecl_log1p_simple(x); + return ecl_make_singlefloat(log1pf(number_to_float(x))); } static cl_object @@ -222,6 +220,6 @@ ecl_log1p_complex(cl_object x) } MATH_DEF_DISPATCH1(log1p, @[si::log1p], @[number], - ecl_log1p_rational, ecl_log1p_single_float, - ecl_log1p_double_float, ecl_log1p_long_float, + ecl_log1p_rational, ecl_log1p_simple, ecl_log1p_rational, + ecl_log1p_single_float, ecl_log1p_double_float, ecl_log1p_long_float, ecl_log1p_complex); diff --git a/src/c/numbers/sin.d b/src/c/numbers/sin.d index 21c43e996..f2099b3b7 100644 --- a/src/c/numbers/sin.d +++ b/src/c/numbers/sin.d @@ -70,6 +70,6 @@ ecl_sin_complex(cl_object x) } MATH_DEF_DISPATCH1(sin, @[sin], @[number], - ecl_sin_rational, ecl_sin_single_float, - ecl_sin_double_float, ecl_sin_long_float, + ecl_sin_rational, ecl_sin_rational, ecl_sin_rational, + ecl_sin_single_float, ecl_sin_double_float, ecl_sin_long_float, ecl_sin_complex); diff --git a/src/c/numbers/sinh.d b/src/c/numbers/sinh.d index 11795fe01..40c89a1fd 100644 --- a/src/c/numbers/sinh.d +++ b/src/c/numbers/sinh.d @@ -71,6 +71,6 @@ ecl_sinh_complex(cl_object x) } MATH_DEF_DISPATCH1(sinh, @[sinh], @[number], - ecl_sinh_rational, ecl_sinh_single_float, - ecl_sinh_double_float, ecl_sinh_long_float, + ecl_sinh_rational, ecl_sinh_rational, ecl_sinh_rational, + ecl_sinh_single_float, ecl_sinh_double_float, ecl_sinh_long_float, ecl_sinh_complex); diff --git a/src/c/numbers/sqrt.d b/src/c/numbers/sqrt.d index 00abb13c7..c95fbf024 100644 --- a/src/c/numbers/sqrt.d +++ b/src/c/numbers/sqrt.d @@ -84,6 +84,6 @@ ecl_sqrt_complex(cl_object x) } MATH_DEF_DISPATCH1(sqrt, @[sqrt], @[number], - ecl_sqrt_rational, ecl_sqrt_single_float, - ecl_sqrt_double_float, ecl_sqrt_long_float, + ecl_sqrt_rational, ecl_sqrt_rational, ecl_sqrt_rational, + ecl_sqrt_single_float, ecl_sqrt_double_float, ecl_sqrt_long_float, ecl_sqrt_complex); diff --git a/src/c/numbers/tan.d b/src/c/numbers/tan.d index 4c0780b09..108027c8c 100644 --- a/src/c/numbers/tan.d +++ b/src/c/numbers/tan.d @@ -75,6 +75,6 @@ ecl_tan_complex(cl_object x) } MATH_DEF_DISPATCH1(tan, @[tan], @[number], - ecl_tan_rational, ecl_tan_single_float, - ecl_tan_double_float, ecl_tan_long_float, + ecl_tan_rational, ecl_tan_rational, ecl_tan_rational, + ecl_tan_single_float, ecl_tan_double_float, ecl_tan_long_float, ecl_tan_complex); diff --git a/src/c/numbers/tanh.d b/src/c/numbers/tanh.d index f75c5538f..185330712 100644 --- a/src/c/numbers/tanh.d +++ b/src/c/numbers/tanh.d @@ -63,6 +63,6 @@ ecl_tanh_complex(cl_object x) } MATH_DEF_DISPATCH1(tanh, @[tanh], @[number], - ecl_tanh_rational, ecl_tanh_single_float, - ecl_tanh_double_float, ecl_tanh_long_float, + ecl_tanh_rational, ecl_tanh_rational, ecl_tanh_rational, + ecl_tanh_single_float, ecl_tanh_double_float, ecl_tanh_long_float, ecl_tanh_complex); diff --git a/src/h/impl/math_dispatch.h b/src/h/impl/math_dispatch.h index 8954c9b13..0f338127a 100644 --- a/src/h/impl/math_dispatch.h +++ b/src/h/impl/math_dispatch.h @@ -25,7 +25,7 @@ typedef cl_object (*math_one_arg_fn)(cl_object); #else #define MATH_LONG_DOUBLE(opt) #endif -#define MATH_DEF_DISPATCH1(name,id,type,rational,single_float,double_float,long_float,complex) \ +#define MATH_DEF_DISPATCH1(name,id,type,fix,big,ratio,single_float,double_float,long_float,complex) \ static cl_object name##failed(cl_object x) { \ FEwrong_type_only_arg(id, x, type); \ } \ @@ -33,7 +33,7 @@ typedef cl_object (*math_one_arg_fn)(cl_object); name##failed, /* t_start */ \ name##failed, /* t_list */ \ name##failed, /* t_character */ \ - rational, rational, rational, /* t_fixnum, bignum, ratio */ \ + fix, big, ratio, /* t_fixnum, bignum, ratio */ \ single_float, double_float, /* t_singlefloat, t_doublefloat */ \ MATH_LONG_DOUBLE(long_float) /* t_longfloat, optional */ \ complex }; \